SQL中怎样使用ROLLUP生成多层级的汇总报表?

落瑶姑娘_3552

落瑶姑娘_3552

2026-10-23

302人浏览

原创

rollup是group by的扩展修饰符,用于自动生成多级小计和总计行;本质区别在于group by仅返回单一粒度分组,而group by rollup(a,b,c)按(a,b,c)→(a,b)→(a)→()逐级上卷生成四层结果,null为占位符而非缺失值,需用grouping()函数精准识别汇总层级。

sql中怎样使用rollup生成多层级的汇总报表?

ROLLUP 是什么,它和 GROUP BY 有什么本质区别?

ROLLUP 不是独立语句,而是 GROUP BY 的扩展修饰符,用于在分组结果中自动添加多级小计行(subtotal)和总计行(grand total)。关键区别在于:GROUP BY a, b, c 只产出一个粒度的分组;而 GROUP BY ROLLUP(a, b, c) 会按 (a,b,c) → (a,b) → (a) → () 的顺序逐级上卷,生成四层结果。

常见错误是把它当成“自动画报表”的黑盒——实际它只负责生成带 NULL 占位符的聚合行,后续展示逻辑(比如把 NULL 显示为“合计”)得自己处理。

使用场景集中在财务、销售、BI 报表这类需要“钻取式汇总”的需求,比如:按部门→团队→员工统计销售额,同时要看到每个团队小计、部门总计、全公司总计。

怎么写一个能用的 ROLLUP 查询?注意 NULL 和排序问题

ROLLUP 生成的上卷行会在对应列填入 NULL,但这个 NULL 是占位符,不是真实数据缺失。如果不加处理,报表里会出现一堆 NULL,容易误导。

SELECT 
  COALESCE(dept, '【部门总计】') AS dept,
  COALESCE(team, '【团队小计】') AS team,
  COALESCE(emp_name, '【员工汇总】') AS emp_name,
  SUM(sales) AS total_sales
FROM sales_data
GROUP BY ROLLUP(dept, team, emp_name)
ORDER BY dept, team, emp_name;

注意三点:

  • COALESCE 替换 NULL 是必须的,否则无法区分“真实为空的员工名”和“上卷占位符”
  • ORDER BY 必须和 ROLLUP 列顺序一致,否则小计行可能被插到中间,破坏层级感
  • 如果某列本身允许 NULL,仅靠 COALESCE 不够,得加辅助字段标识层级,比如 GROUPING(dept) 返回 1 表示该行是上卷行

GROUPING() 函数为什么不能省?它解决什么真实问题?

当原始数据里就有 NULL 值(比如某个员工尚未分配团队),仅靠 COALESCE(team, '小计') 会把真实 NULL 和上卷占位符混为一谈。这时必须用 GROUPING() 来精确识别。

GROUPING(dept) 在 dept 是上卷行时返回 1,否则返回 0;支持多列组合判断,比如 GROUPING(dept, team) = 2 表示 dept 和 team 都是上卷(即只按 emp_name 分组那层)。

典型用法:

  • 用 CASE WHEN GROUPING(dept) = 1 THEN '总计' ELSE dept END 安全替换
  • 在 WHERE 中过滤掉某级上卷行:HAVING GROUPING(team) = 0(只保留有具体 team 的行)
  • 排序时让上卷行排在末尾:ORDER BY GROUPING(dept), dept

ROLLUP 和 CUBE、GROUPING SETS 性能差异大吗?

ROLLUP(a,b,c) 生成 4 组分组(a,b,c / a,b / a / 空);CUBE(a,b,c) 生成 8 组(所有排列组合);GROUPING SETS((a,b,c),(a,b),(a)) 则只生成你明确列出的三组。

性能上:行数越多,聚合计算和内存占用越高。尤其在大数据量 + 多列 ROLLUP 时,执行计划可能退化成多次扫描。建议:

  • 优先用 GROUPING SETS 替代 ROLLUP,如果只需要部分层级
  • 避免对高基数列(如用户 ID)做 ROLLUP
  • 在 PostgreSQL 中,ROLLUP 可能触发哈希聚合优化;但在 MySQL 8.0+ 才支持,旧版只能模拟(用 UNION ALL)

真正麻烦的是嵌套逻辑——比如想对“部门小计”再按年份做二次上卷,ROLLUP 本身不支持嵌套,得用子查询或 CTE 拆开处理。这点很容易在设计初期被忽略。

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

2023.10.12

4443

8

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.27

931

4

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

2024.02.23

1169

5

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

2024.03.06

6401

10

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

2024.03.06

3203

4

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

2024.04.07

6360

11

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

2024.04.29

8701

6

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

2024.04.29

1170

5

sql中删除一列的命令是什么
sql中删除一列的命令是什么

在sql中,使用alter table语句可以删除一列,语法为:alter table table_name drop column column_name。想了解更多sql的相关内容,可以阅读本专题下面的文章。

2024.04.29

1032

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
热门推荐
/
最新课程
phpStudy极速入门视频教程
phpStudy极速入门视频教程

共6课时 | 54.7万人学习

独孤九贱(4)_PHP视频教程
独孤九贱(4)_PHP视频教程

共89课时 | 133.9万人学习