SQL使用CASE WHEN统计员工数据出现结果冲突的原因及效率咨询
问题原因及解决方案
1. CASE WHEN写法结果冲突的核心原因
你在单句查询中误用了COUNT()聚合函数:
COUNT()仅统计非空值,你给CASE WHEN加了ELSE 0的逻辑,不管判断条件是否成立,最终返回的都是1或0这两个非空数值- 这就导致两个
COUNT()的返回值完全相等,都是facebook_employees表的总员工数 - 你的判断条件用的是严格大于
>,所以条件永远不成立,最终只会返回ELSE分支的结果,反转判断条件相当于直接调换了ELSE分支的内容,自然会得到相反的结果
2. 单句CASE WHEN的正确写法
有两种修正思路:
思路1:用SUM()替代COUNT()
SUM可以直接累加符合条件的标记值,得到对应群体的总人数:
SELECT CASE WHEN SUM(CASE WHEN location = 'US' THEN 1 ELSE 0 END) > SUM(CASE WHEN is_senior = true THEN 1 ELSE 0 END) THEN 'More USA-based' ELSE 'More seniors' END AS what_do_we_have_more_of FROM facebook_employees
思路2:去掉CASE WHEN的ELSE 0逻辑
不写ELSE时,不符合条件的行默认返回NULL,COUNT会自动忽略NULL值,得到符合条件的人数:
SELECT CASE WHEN COUNT(CASE WHEN location = 'US' THEN 1 END) > COUNT(CASE WHEN is_senior = true THEN 1 END) THEN 'More USA-based' ELSE 'More seniors' END AS what_do_we_have_more_of FROM facebook_employees
修正后的单句查询结果和你的CTE子查询版本完全一致。
3. 两种写法的效率对比
修正后的单句CASE WHEN写法效率远高于CTE+FULL JOIN的子查询写法:
- 单句写法仅需要对
facebook_employees表做一次全量扫描,没有额外的中间表存储和关联操作 - 子查询写法需要先两次过滤表得到两个临时CTE结果,再执行全连接,最后做聚合,IO开销和计算开销都更高,数据量越大性能差距越明显
内容的提问来源于stack exchange,提问作者Ricardo Francois
相关产品推荐
相关产品推荐

