如何编写实现横纵向汇总的SQL查询,按年份单行展示费用总计?
实现横纵向汇总的SQL查询方案
基础行转列+汇总实现(以MySQL为例)
假设你的费用表名为annual_expenses,包含字段:year(年份)、expense_category(费用类别,如"办公费""差旅费"等)、amount(费用金额)。下面的SQL可以实现类似你提供的Excel表格的横纵向汇总效果:
-- 先统计各年份的分类费用及年度小计,再生成总计行 WITH year_category_totals AS ( SELECT year, SUM(CASE WHEN expense_category = '办公费' THEN amount ELSE 0 END) AS 办公费, SUM(CASE WHEN expense_category = '差旅费' THEN amount ELSE 0 END) AS 差旅费, SUM(CASE WHEN expense_category = '业务招待费' THEN amount ELSE 0 END) AS 业务招待费, SUM(CASE WHEN expense_category = '水电费' THEN amount ELSE 0 END) AS 水电费, SUM(amount) AS 年度总计 FROM annual_expenses GROUP BY year ), grand_total AS ( SELECT '总计' AS year, SUM(办公费) AS 办公费, SUM(差旅费) AS 差旅费, SUM(业务招待费) AS 业务招待费, SUM(水电费) AS 水电费, SUM(年度总计) AS 年度总计 FROM year_category_totals ) SELECT * FROM year_category_totals UNION ALL SELECT * FROM grand_total ORDER BY CASE WHEN year = '总计' THEN 1 ELSE 0 END, year;
核心逻辑说明
- 行转列:通过
CASE WHEN结合SUM函数,将不同费用类别转为单独列,实现每年一行展示各类费用。 - 年度小计:
SUM(amount)直接计算每一年的所有费用总和,对应结果中的"年度总计"列。 - 总计行:通过子查询
grand_total计算所有年份的各类费用总和,再用UNION ALL追加到结果末尾。 - 排序控制:最后通过
ORDER BY确保"总计"行排在所有年份行之后,年份按升序排列。
适配其他数据库的调整
- SQL Server:语法基本一致,直接使用即可。
- Oracle:需注意类型兼容,可将年份字段转为字符串(如
TO_CHAR(year)),确保"总计"行的year列类型统一。
注意事项
- 替换代码中的费用类别为你表中实际的类别名称,若类别较多,需逐个添加对应的
CASE WHEN分支。 - 若表中有额外维度(如部门),可在
GROUP BY中加入对应字段,同步调整行转列逻辑即可。
内容的提问来源于stack exchange,提问作者Mike
相关产品推荐
相关产品推荐

