3 Where 子句没有条目给我 NULL
3 Where clauses one no entry gives me NULL
我有三个 tables,支出,收入,用户。我首先尝试获取用于获取有关用户的收入和支出信息的用户 ID。有了这个,我还与 DISTINCT 一起计算并减去它以获得当前收入。问题是如果 table 中的任何一个都没有输入示例支出 table 所以我得到 NULL 而不是数字。我该如何解决这个问题。我尝试了 IFNULL 但没有成功
我就是这样做的
SELECT SUM(DISTINCT user_earnings.amount) -
SUM(DISTINCT user_payouts.payout_amount) as total_earnings
FROM user, user_earnings, user_payouts
WHERE user.id = 103
and user_earnings.user_id = user.id
and user_payouts.user_id = user.id
编辑:我制作了当前的 tables
user_earnings(问题仅在于 user_id 103
id user_id amount
1 102 250
2 102 1000
3 101 5000
4 102 352
18 102 375
19 102 442
20 103 338 <-----
user_payouts
id user_id payout_amount
1 102 500
2 102 100
3 101 1000
用户
id payout_address
102 ***
103 ***
如您所见,付款没有关于 user_id 103 的条目,因为他从未进行过付款。这就是为什么我得到 null(我认为)
注1:
我绝对不会以这种方式使用 Distinct ...如果用户将来有另一个 earned_amount 用于 338,则第二个 338 不会添加到总数中。
注2:
请参阅我对 COALESCE 而不是 IFNULL 的用法。
注3:
我更新了您的连接语法。请确认我保留了您的加入。
编辑: 更新了答案和 fiddle 以解释每个用户的重复 earned_amount 以及每个用户的重复 payout_amounts
查看 Fiddle 以注意为用户 103 (400 + 400 - 100 - 100))
输入的两个重复项
SELECT (
COALESCE(ue.earned_amount,0) - COALESCE(up.payout_amount,0)
) AS total_earnings
FROM user u
JOIN (SELECT user_id, SUM(earned_amount) AS earned_amount
FROM Earned
GROUP BY user_id) ue
ON ue.user_id = u.id
JOIN (SELECT user_id, SUM(payout_amount) AS payout_amount
FROM Payouts
GROUP BY user_id) up
ON up.user_id = u.id
WHERE u.id = 103
性能说明:
如果您的 Earned 或 Payout tables 预计会很大,那么一些改进性能的想法将会是。
通过向每个嵌套查询添加一个 Where 子句来限制嵌套查询的 returned 结果集的大小,这样它们只有 return 结果 user_id 103 .
为 user_id 列的 Earned 和 Payout 添加索引。
或首先创建这些连接到带有索引的临时 table,然后将临时 table 连接到此查询
试试这个:
SELECT u.id,
(SUM(DISTINCT ue.amount) -
COALESCE(SUM(DISTINCT up.payout_amount),0)) as total_earnings
FROM
user u
left outer join user_earnings ue on u.id = ue.user_id
left outer join user_payouts up on u.id = up.user_id
WHERE
u.id = 103;
抱歉,我没有在上面付出足够的努力。虽然它适用于小样本,但上面的内容会分解为更大的样本,因为您要过滤掉单个用户获得两次相同金额的支出的任何实例。
我认为这是您真正的解决方案:
SELECT
u.id,
(ue.earnings - up.payouts) as total_earnings
FROM
user u
inner join
(select distinct
u1.id,
SUM(COALESCE(ue.amount,0)) as earnings
from
user u1
left join user_earnings ue on u1.id = ue.user_id group by u1.id) ue on u.id = ue.id
inner join
(select distinct
u1.id,
SUM(COALESCE(up.payout_amount,0)) as payouts
from
user u1
left join user_payouts up on u1.id = up.user_id group by u1.id) up on u.id = up.id
WHERE
u.id = 103;
只是为了好玩,这是另一个选项,更短:
SELECT
u.id,
((select COALESCE(SUM(ue.amount),0) from user_earnings ue where ue.user_id = u.id) -
(select COALESCE(SUM(up.payout_amount),0) from user_payouts up where up.user_id = u.id)) as total_earnings
FROM
user u
WHERE
u.id = 103;
您有 3 个问题 -- DISTINCT
、JOIN
后跟 GROUP BY
,以及无法处理 NULL
。
SELECT u.id,
(
SELECT ( IFNULL(SUM(amount), 0)
FROM user_earnings WHERE user_id = u.id ) -
SELECT ( IFNULL(SUM(payout_amount), 0 )
FROM user_payouts WHERE user_id = u.id )
) as total_earnings
FROM user u
WHERE u.id = 103;
应该都解决了。
DISTINCT
已经讨论过 - 给定用户可能有重复值。
JOIN
后跟 GROUP BY
-- 我称之为 "inflate-deflate syndrone"。 JOIN
首先发生,从而增加了行数,然后 GROUP BY
试图对其进行补偿。通常这是一个性能问题;在你的情况下,它也会破坏数据。
讨论了 NULL
,但我认为这个公式是 'correct'。
这是 'rare' 的情况,子查询优于 LEFT JOIN
。它避免了 SUM
的过度计算。 ghenghy 的第一个解决方案可能与 单个 u.id
一样好;我的应该适用于多个 ID。
我有三个 tables,支出,收入,用户。我首先尝试获取用于获取有关用户的收入和支出信息的用户 ID。有了这个,我还与 DISTINCT 一起计算并减去它以获得当前收入。问题是如果 table 中的任何一个都没有输入示例支出 table 所以我得到 NULL 而不是数字。我该如何解决这个问题。我尝试了 IFNULL 但没有成功
我就是这样做的
SELECT SUM(DISTINCT user_earnings.amount) -
SUM(DISTINCT user_payouts.payout_amount) as total_earnings
FROM user, user_earnings, user_payouts
WHERE user.id = 103
and user_earnings.user_id = user.id
and user_payouts.user_id = user.id
编辑:我制作了当前的 tables user_earnings(问题仅在于 user_id 103
id user_id amount
1 102 250
2 102 1000
3 101 5000
4 102 352
18 102 375
19 102 442
20 103 338 <-----
user_payouts
id user_id payout_amount
1 102 500
2 102 100
3 101 1000
用户
id payout_address
102 ***
103 ***
如您所见,付款没有关于 user_id 103 的条目,因为他从未进行过付款。这就是为什么我得到 null(我认为)
注1: 我绝对不会以这种方式使用 Distinct ...如果用户将来有另一个 earned_amount 用于 338,则第二个 338 不会添加到总数中。
注2: 请参阅我对 COALESCE 而不是 IFNULL 的用法。
注3: 我更新了您的连接语法。请确认我保留了您的加入。
编辑: 更新了答案和 fiddle 以解释每个用户的重复 earned_amount 以及每个用户的重复 payout_amounts
查看 Fiddle 以注意为用户 103 (400 + 400 - 100 - 100))
输入的两个重复项SELECT (
COALESCE(ue.earned_amount,0) - COALESCE(up.payout_amount,0)
) AS total_earnings
FROM user u
JOIN (SELECT user_id, SUM(earned_amount) AS earned_amount
FROM Earned
GROUP BY user_id) ue
ON ue.user_id = u.id
JOIN (SELECT user_id, SUM(payout_amount) AS payout_amount
FROM Payouts
GROUP BY user_id) up
ON up.user_id = u.id
WHERE u.id = 103
性能说明:
如果您的 Earned 或 Payout tables 预计会很大,那么一些改进性能的想法将会是。
通过向每个嵌套查询添加一个 Where 子句来限制嵌套查询的 returned 结果集的大小,这样它们只有 return 结果 user_id 103 .
为 user_id 列的 Earned 和 Payout 添加索引。
或首先创建这些连接到带有索引的临时 table,然后将临时 table 连接到此查询
试试这个:
SELECT u.id,
(SUM(DISTINCT ue.amount) -
COALESCE(SUM(DISTINCT up.payout_amount),0)) as total_earnings
FROM
user u
left outer join user_earnings ue on u.id = ue.user_id
left outer join user_payouts up on u.id = up.user_id
WHERE
u.id = 103;
抱歉,我没有在上面付出足够的努力。虽然它适用于小样本,但上面的内容会分解为更大的样本,因为您要过滤掉单个用户获得两次相同金额的支出的任何实例。
我认为这是您真正的解决方案:
SELECT
u.id,
(ue.earnings - up.payouts) as total_earnings
FROM
user u
inner join
(select distinct
u1.id,
SUM(COALESCE(ue.amount,0)) as earnings
from
user u1
left join user_earnings ue on u1.id = ue.user_id group by u1.id) ue on u.id = ue.id
inner join
(select distinct
u1.id,
SUM(COALESCE(up.payout_amount,0)) as payouts
from
user u1
left join user_payouts up on u1.id = up.user_id group by u1.id) up on u.id = up.id
WHERE
u.id = 103;
只是为了好玩,这是另一个选项,更短:
SELECT
u.id,
((select COALESCE(SUM(ue.amount),0) from user_earnings ue where ue.user_id = u.id) -
(select COALESCE(SUM(up.payout_amount),0) from user_payouts up where up.user_id = u.id)) as total_earnings
FROM
user u
WHERE
u.id = 103;
您有 3 个问题 -- DISTINCT
、JOIN
后跟 GROUP BY
,以及无法处理 NULL
。
SELECT u.id,
(
SELECT ( IFNULL(SUM(amount), 0)
FROM user_earnings WHERE user_id = u.id ) -
SELECT ( IFNULL(SUM(payout_amount), 0 )
FROM user_payouts WHERE user_id = u.id )
) as total_earnings
FROM user u
WHERE u.id = 103;
应该都解决了。
DISTINCT
已经讨论过 - 给定用户可能有重复值。JOIN
后跟GROUP BY
-- 我称之为 "inflate-deflate syndrone"。JOIN
首先发生,从而增加了行数,然后GROUP BY
试图对其进行补偿。通常这是一个性能问题;在你的情况下,它也会破坏数据。
讨论了 NULL
,但我认为这个公式是 'correct'。
这是 'rare' 的情况,子查询优于 LEFT JOIN
。它避免了 SUM
的过度计算。 ghenghy 的第一个解决方案可能与 单个 u.id
一样好;我的应该适用于多个 ID。