Mysql 3其中第1条无条目为空
我有三个表格,支出,收入,用户。我尝试首先获取用户ID,用于获取有关用户的收入和支出信息。有了这个,我还可以和DISTINCT一起计算并减去它,得到当前的收益。问题是,如果表中的任何一个都没有条目,例如payouts表,那么我得到的是NULL而不是number。我怎样才能解决这个问题。我尝试了IFNULL,但没有成功 我就是这样做的Mysql 3其中第1条无条目为空,mysql,null,mariadb,Mysql,Null,Mariadb,我有三个表格,支出,收入,用户。我尝试首先获取用户ID,用于获取有关用户的收入和支出信息。有了这个,我还可以和DISTINCT一起计算并减去它,得到当前的收益。问题是,如果表中的任何一个都没有条目,例如payouts表,那么我得到的是NULL而不是number。我怎样才能解决这个问题。我尝试了IFNULL,但没有成功 我就是这样做的 SELECT SUM(DISTINCT user_earnings.amount) - SUM(DISTINCT user_payouts.pay
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
编辑:我创建了当前表
用户收入问题仅限于用户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 <-----
使用者
正如您所看到的,payouts没有关于用户_id 103的条目,因为他从未进行过支付。这就是我得到空值的原因我想注1:
我绝对不会以这种方式使用Distinct。。。如果用户将来有另一笔338的收入,第二笔338将不会添加到总数中
注2:
请参阅我对COALESCE而不是IFNULL的用法
注3:
我更新了你的连接语法。请确认我按要求保留了您的加入
编辑:更新答案并对每个用户的重复已赚金额以及每个用户的重复支付金额进行调整
查看FIDLE以注意为用户103 400+400-100-100输入的两个副本
点击
业绩说明:
如果您的收入表或支出表预计会很大,那么将有一些改进绩效的想法
通过向每个查询添加Where子句来限制嵌套查询返回结果集的大小,以便它们只返回用户_id 103的结果
将索引添加到“用户id”列的“收入”和“支出”
或者首先创建这些到带有索引的临时表的连接,然后将临时表连接到此查询
试试这个:
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后跟groupby以及无法处理NULL
应该解决所有问题
DISTINCT已经讨论过了-对于给定用户可能存在重复值。
加入,然后是分组-我称之为充气-放气合成蜂。连接首先发生,从而增加了行数,然后GROUPBY尝试对此进行补偿。通常这是一个性能问题;在你的情况下,它也会破坏数据。
讨论了NULL,但我认为这个公式是“正确的”。
这是一种“罕见”的情况,其中子查询优于左连接。它避免了总和的过度计算。ghenghy的第一个解决方案可能同样适用于一个u.id;我的应该适用于多个ID。推广explict的使用,Aaron Bertrand写了一篇很好的文章。谢谢。我会查一查。加入对我来说并不容易,因为我不太了解mysql,我只是尝试了一下。我没有得到0或null,但我得到的总收入=-586,这是错误的。我有一项收入。它的数量和用户103的值为338。它不是零,所以它是一个开始让我进一步研究一下。你说你在ue中有一个用户ID 103条目。金额为338。用户ID 103在up.payout\u amount中有什么??它不是总共1023个,是吗?我只是编辑我的主线程。在那里你可以检查一下。用户ID 103的支付金额为空,因为他从未进行过支付。一切都只是一个例子,而不是真实的东西:POK,building answer Now这是例外。我还为支出添加了一个条目。价值观一切都是正确的,谢谢。这太疯狂了。我需要学习连接的东西。
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;
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;