使用CTE、COUNT与GROUP BY时如何返回无数据分组的0值?
解决空分组显示0的问题
你的核心问题是原查询仅基于现有数据生成分组,无流失客户的分组不会出现在CTE中,导致GROUP BY后无法返回这些分组。要实现所有分组都显示、空分组统计值为0的需求,需要先构造完整的分组集合,再与统计结果做左连接,确保所有分组被保留。
修正后的SQL语句
WITH all_score_groups AS ( -- 构造所有需要的目标分组 SELECT '1-30' AS churn_score_group UNION ALL SELECT '31-50' AS churn_score_group UNION ALL SELECT '51-80' AS churn_score_group UNION ALL SELECT '81-100' AS churn_score_group ), churn_stats AS ( -- 统计每个分组的流失客户数量 SELECT CASE WHEN churn_score BETWEEN 1 AND 30 THEN '1-30' WHEN churn_score BETWEEN 31 AND 50 THEN '31-50' -- 修正原代码笔误:原写为31-60 WHEN churn_score BETWEEN 51 AND 80 THEN '51-80' WHEN churn_score BETWEEN 81 AND 100 THEN '81-100' END AS churn_score_group, COUNT(*) AS churn_count FROM churn_status WHERE churn_label = 'Yes' -- 仅统计流失客户 GROUP BY churn_score_group ) -- 左连接确保所有分组保留,用COALESCE将NULL转为0 SELECT g.churn_score_group, COALESCE(s.churn_count, 0) AS churn_count FROM all_score_groups g LEFT JOIN churn_stats s ON g.churn_score_group = s.churn_score_group ORDER BY g.churn_score_group;
关键说明
- 固定分组集合:通过
UNION ALL生成所有目标分组作为左表,保证无论是否有数据,分组都会被返回。 - 左连接统计结果:左连接会保留左表的所有行,右表无匹配数据时统计值为
NULL。 - COALESCE函数:将
NULL替换为0,实现空分组显示0的需求。 - 修正原SQL错误:原CASE语句中
31-60是笔误,需改为31-50;原CTE中Churn_value字段不存在,已移除该错误字段。
内容的提问来源于stack exchange,提问作者Lana
相关产品推荐
相关产品推荐

