SUM(cond)与COUNT(cond)搭配HAVING子句的行为差异咨询
关于SUM与COUNT在SQL查询中的差异问题解答
一、HAVING子句中SUM可用但COUNT失效的原因
- COUNT()的核心逻辑是统计所有非NULL值的行数,不管值是0还是1,只要表达式结果不为NULL就会被计数。
- 你写的
COUNT(o.product_name = 'Bread')里,product_name = 'Bread'永远返回1(匹配)或0(不匹配),不存在NULL的情况,因此这个COUNT结果等价于COUNT(*),即该客户的总订单数。只要客户有订单,这个值必然大于0,完全起不到“判断是否购买过Bread”的作用。 - 而SUM()会把1和0累加,
SUM(o.product_name = 'Bread')>0代表至少有一行匹配Bread,刚好符合你的需求。
如果一定要用COUNT实现相同逻辑,需要用CASE语句让不匹配的情况返回NULL(COUNT不会统计NULL):
SELECT c.customer_id, c.customer_name FROM customers c JOIN orders o USING (customer_id) GROUP BY c.customer_id, c.customer_name HAVING COUNT(CASE WHEN o.product_name = 'Bread' THEN 1 END) > 0 AND COUNT(CASE WHEN o.product_name = 'Milk' THEN 1 END) > 0 AND COUNT(CASE WHEN o.product_name = 'Eggs' THEN 1 END) = 0 ORDER BY customer_name
二、SELECT子句中COUNT与SUM的表现差异
COUNT(product_name = 'Bread')返回的是该客户的总订单数,因为每个订单行的表达式都返回0或1(非NULL),COUNT会把所有行统计进去。你觉得“COUNT有效”,其实是它返回了一个有意义的数字,但这个数字并不是购买Bread的次数。SUM(product_name = 'Bread')返回的才是该客户购买Bread的次数,它把匹配时的1累加,不匹配的0不影响总和。你觉得“SUM无效”可能是误解了输出——比如客户没买过Bread时SUM返回0,这其实是正确结果,而COUNT会返回该客户的总订单数。
举个例子:某客户有3个订单,其中1个是Bread,2个是其他产品,那么:
COUNT(product_name = 'Bread')返回3SUM(product_name = 'Bread')返回1
两者都是正确的,只是统计维度不同。
内容的提问来源于stack exchange,提问作者user25856037
相关产品推荐
相关产品推荐

