SQL SUM 和 GROUP BY
Posted
技术标签:
【中文标题】SQL SUM 和 GROUP BY【英文标题】:SQL SUM and GROUP BY 【发布时间】:2020-01-19 18:40:06 【问题描述】:我不明白为什么 SQL 给我两个非常不同的数字,用于计算表中的值的简单 GROUP BY。我使用的是 2 列的 SUM。
我将尝试将其分解为系统中最简单的关键组件。
Ledger:
| increase | decrease | userid | currency
Users:
| email | role |
userid
在 users 表上是 id
的 FK,没有孤立行。
现在开始查询:
SELECT
SUM(l.increase) - SUM(l.decrease) as total
FROM ledger l
JOIN users u ON l.userid = u.id AND u.role = 'customer'
WHERE l.currency = 'USD'
GROUP BY u.email
ORDER BY total DESC
以上产生了 145 行用户。我可以把它放在一个子查询中以获得我认为是真正的 SUM
SELECT SUM(tmp.total) FROM (<ABOVE_AS_SUBQUERY>) as tmp
并且我得到 8042。
这是我的第二个查询:
SELECT
SUM(l.increase) - SUM(l.decrease) as total
FROM ledger l
JOIN users u ON l.userid = u.id AND u.role = 'customer'
WHERE l.currency = 'USD'
GROUP BY u.role
ORDER BY total DESC
这次我按角色分组,事实上,我可以将 GROUP BY 全部删除,它的行为是一样的。 我得到 99104。
当然结果应该是一样的。特别是因为我的加入条件已经在过滤role='customer'
。
GROUP BY u.email
给了我一组独特的每封电子邮件的总数,但我不明白为什么删除 GROUP by 给我的数字远远超出了 GROUP BY 之后数据集中的数字,很明显有些奇怪正在发生。为什么结果行不只是所有这些电子邮件的总和并给我 8042?
谢谢
编辑:这是SQL Fiddle。正如我最初预期的那样,这 2 个查询返回相同的结果。我无法在这个小提琴中复制这个问题,这意味着它与数据有关,但这里只有 2 个表在起作用。我可以使用什么样的数据来复制我所描述的内容?
【问题讨论】:
样本数据和期望的结果会有所帮助。如果您可以在少量数据样本上复制这一点,那么 db fiddle 也会有很大帮助。 @phi 为什么组在这种情况下很重要?我的加入也是ON u.role = 'customer'
。我实际上只选择具有客户角色的行,因此带或不带组的 SUM 是相同的。 GROUP 电子邮件的 SUM 也将是相同的,因为它仍然会获得每封唯一电子邮件的 SUM,总体上将达到相同的数量。
添加了一个小提琴:)
我没有说团队很重要。我只是回应“我不明白为什么删除 GROUP by 会给我”,以确认您对 GROUP BY 本身的期望的任何部分是相关的。 PS请将您的问题所需的所有内容都放入其中,包括代码,而不仅仅是链接。请不要附加/插入编辑部分,编辑以重写为可能的最佳演示文稿。 PS 要找到较小的代表性问题输入,请继续将问题数据减半,直到您对适当的子集进行二进制搜索。另外:NULL 是可疑的罪魁祸首,因此请为它们选择/计数/排序。
您在数据中显示空值,您是否理解解决每个 SUM & + 得到不同总和的答案,因为它们对空值的处理方式不同?您是否使用问题数据查看了每个子表达式结果,以查看何时没有得到您期望的结果?分别选择 SUM,而不仅仅是它们的差异? (更基本的调试。)
【参考方案1】:
如果没有GROUP BY
,我会相信答案。
可能发生的情况是NULL
值“干扰”了结果。 SUM()
忽略 NULL
值,因此如果所有非 NULL
值将被加在一起。但是,+
不会忽略 NULL
值。如果任一操作数是NULL
,那么结果是NULL
。
例如,如果您有一个名称,其中所有decrease
值都是NULL
。例如:
email role increase decrease
a 1 10 5
b 1 20 NULL
在这个简单的示例中,通过电子邮件进行汇总会导致:
a 5 -- 10 - 5 = 5
b NULL -- 20 - NULL = NULL
但按角色应该是:
1 25 -- sum(10 + 20) - sum(5 + NULL) = 30 - 5 = 25
您没有在问题中提及 NULL
值,但它们可能是罪魁祸首。
【讨论】:
好主意,正如你所说,我确实有 NULLS。我认为SUM(column)
虽然不关心 NULLS。 SUM(decrease)
在您的示例中将是 (5 + null),SQL 将其解释为 5
。它不会对每行的(增加 - 减少)求和。不过,我按角色来看,它的行为很可能是这样的……很有趣,但我希望看到的数字会更低,而不是更高!
我越看越觉得这可能与 NULLS 有关。我可以将值提取到 MS excel 中,并以最简单的方式来确定结果,并得到 99k 值。以上是关于SQL SUM 和 GROUP BY的主要内容,如果未能解决你的问题,请参考以下文章