Oracle SQL Case语句如何添加包含所有场景的汇总行?
Oracle SQL 实现分类转换并添加汇总行的解决方案
你的原SQL存在两个核心问题:
- CASE语句的匹配顺序导致最后一个条件永远不会生效:CASE是按从上到下的顺序匹配条件,前三个条件已经覆盖了
type='b'、type='g'、type IS NULL所有场景,最后一行When q1.type in (NULL, 'b', 'g') then 'total'永远不会被触发。 - CASE语句无法生成额外的汇总行:CASE只能对每行数据进行值转换,不能凭空生成一条汇总记录,必须通过分组聚合+合并结果集或者ROLLUP扩展分组的方式实现。
方案一:使用UNION ALL合并明细行与汇总行
如果需要明确分开明细统计和总行统计,可以用UNION ALL将两类结果合并:
-- 统计各分类的数量 SELECT CASE WHEN q1.type = 'b' THEN 'blue' WHEN q1.type = 'g' THEN 'green' WHEN q1.type IS NULL THEN 'nothing' END AS color, COUNT(*) AS count FROM q1 WHERE q1.type IN ('b', 'g') OR q1.type IS NULL -- 过滤目标范围的数据 GROUP BY CASE WHEN q1.type = 'b' THEN 'blue' WHEN q1.type = 'g' THEN 'green' WHEN q1.type IS NULL THEN 'nothing' END UNION ALL -- 添加汇总行 SELECT 'total' AS color, COUNT(*) AS count FROM q1 WHERE q1.type IN ('b', 'g') OR q1.type IS NULL ORDER BY color; -- 按颜色排序,可调整让汇总行排在指定位置
方案二:使用ROLLUP生成自动汇总行(更简洁)
Oracle的ROLLUP分组函数可以在分组统计的基础上自动生成汇总行,无需额外合并结果集:
SELECT -- 将ROLLUP生成的分组NULL值替换为'total' NVL( CASE WHEN q1.type = 'b' THEN 'blue' WHEN q1.type = 'g' THEN 'green' WHEN q1.type IS NULL THEN 'nothing' END, 'total' ) AS color, COUNT(*) AS count FROM q1 WHERE q1.type IN ('b', 'g') OR q1.type IS NULL -- 按分类字段ROLLUP,自动生成汇总行 GROUP BY ROLLUP( CASE WHEN q1.type = 'b' THEN 'blue' WHEN q1.type = 'g' THEN 'green' WHEN q1.type IS NULL THEN 'nothing' END ) ORDER BY color;
内容的提问来源于stack exchange,提问作者Technissiah
相关产品推荐
相关产品推荐

