多表连接后COUNT(*)与COUNT(columnname)的差异及结果一致原因
COUNT(*) 与 COUNT(w.channel) 的区别及结果一致原因
一、核心区别
COUNT(*):统计分组内的所有行数,不管任何列的值是否为NULL,只要是查询返回的行就会被计入总数。COUNT(w.channel):仅统计分组内w.channel列值不为NULL的行数,如果某行的channel字段是NULL,这一行不会被计数。
二、两段SQL结果一致的原因
这两段查询最终结果相同,主要有两个关键原因:
- JOIN类型与数据匹配逻辑
两段SQL用的都是默认的INNER JOIN(内连接),不管是从accounts开始关联,还是从web_events开始关联,内连接只会保留所有关联表中匹配条件的行,最终得到的结果集行数完全一致。 w.channel字段无NULL值
在当前业务数据集中,web_events表的channel字段要么被设置为非空约束,要么实际存储的数据里没有NULL值。这就导致COUNT(w.channel)的计数范围和COUNT(*)完全重合——所有行的channel都有有效值,不会被排除。
再加上两段SQL的分组字段(s.name, w.channel)和排序逻辑完全一致,最终的统计结果自然完全相同。
附两段SQL代码
第一段:
SELECT s.name, w.channel, COUNT(*) num_events FROM accounts a JOIN web_events w ON a.id = w.account_id JOIN sales_reps s ON s.id = a.sales_rep_id GROUP BY s.name, w.channel ORDER BY num_events DESC;
第二段:
SELECT s.name, w.channel, COUNT(w.channel) FROM web_events w JOIN accounts a ON a.id = w.account_id JOIN sales_reps s ON s.id = a.sales_rep_id GROUP BY s.name, w.channel ORDER BY COUNT(w.channel) DESC
内容的提问来源于stack exchange,提问作者qian duoduo
相关产品推荐
相关产品推荐

