如何在Oracle查询结果末尾添加数值列汇总行
Oracle 查询添加汇总行解决方案
针对你的需求,以下两种方法可以实现给查询结果末尾添加数值列汇总行的效果,其他列留空:
方法一:使用 UNION ALL 直接拼接汇总行(简单直观)
这种方式适合只需要最终总计、不需要中间小计的场景,逻辑清晰容易调试:
完整示例代码
-- 创建测试表 CREATE TABLE funcionario_movimentos ( funcionario_id NUMBER, nome_funcionario VARCHAR2(100), data_movimento DATE, valor NUMBER(10,2) ); -- 插入测试数据 INSERT INTO funcionario_movimentos VALUES (1, 'João Silva', TO_DATE('2024-01-15', 'YYYY-MM-DD'), 12500.00); INSERT INTO funcionario_movimentos VALUES (2, 'Maria Souza', TO_DATE('2024-01-16', 'YYYY-MM-DD'), 15600.00); INSERT INTO funcionario_movimentos VALUES (3, 'Carlos Mendes', TO_DATE('2024-01-17', 'YYYY-MM-DD'), 10000.00); COMMIT; -- 带汇总行的查询语句 SELECT funcionario_id, nome_funcionario, data_movimento, valor FROM funcionario_movimentos UNION ALL SELECT NULL, -- 非数值列置空 NULL, NULL, SUM(valor) -- 对数值列求和 FROM funcionario_movimentos -- 确保汇总行在最后 ORDER BY CASE WHEN funcionario_id IS NULL THEN 1 ELSE 0 END;
执行后会返回3条明细行+1条汇总行,汇总行仅valor列显示38100.00,其余列为空。
方法二:使用 ROLLUP 生成汇总行(支持多级小计)
如果需要后续扩展多级小计(比如按员工、日期分组的小计),可以用ROLLUP配合GROUPING函数控制列显示:
查询代码
SELECT -- GROUPING函数判断是否为汇总行,是则返回NULL CASE WHEN GROUPING(funcionario_id) = 1 THEN NULL ELSE funcionario_id END AS funcionario_id, CASE WHEN GROUPING(nome_funcionario) = 1 THEN NULL ELSE nome_funcionario END AS nome_funcionario, CASE WHEN GROUPING(data_movimento) = 1 THEN NULL ELSE data_movimento END AS data_movimento, SUM(valor) AS valor FROM funcionario_movimentos -- ROLLUP会生成所有组合的小计,这里按所有非数值列分组 GROUP BY ROLLUP(funcionario_id, nome_funcionario, data_movimento) -- 过滤掉中间小计,只保留明细和总计 HAVING GROUPING_ID(funcionario_id, nome_funcionario, data_movimento) IN (0, 7);
关键说明
GROUPING(col):当当前行是该列的汇总行时返回1,否则返回0,用来控制非数值列是否显示为空。GROUPING_ID(...):返回一个二进制数对应的十进制值,这里0代表明细行(所有列都不是汇总),7代表所有列都是汇总的总行(因为3列的二进制111对应十进制7)。
你之前ROLLUP失败的常见原因
- 没有用
GROUPING函数处理非数值列,导致汇总行显示的是分组列的最后一个值,而非空。 - 未过滤中间小计行,生成了多余的分组汇总结果。
内容的提问来源于stack exchange,提问作者Milton
相关产品推荐
相关产品推荐

