WITH ROLLUP 是 MySQL 中 GROUP BY 的扩展语法,用于自动生成分组小计和总计行:按 GROUP BY 字段从左到右逐级上卷,每级汇总时对应字段置为 NULL,最终返回明细、各级小计及总计;需配合 IFNULL 或 GROUPING() 处理 NULL 以标识汇总行,且不支持与 ORDER BY 混用。

什么是 WITH ROLLUP,它真能替代Excel的分类汇总?
可以,但不是“直接拖拽式”的替代——WITH ROLLUP 是 MySQL(及部分兼容引擎)中对 GROUP BY 的扩展,它会在分组结果末尾自动插入小计行和总计行,逻辑上等价于 Excel 中“数据 → 分类汇总”后勾选“汇总结果显示在数据下方”+“替换当前分类汇总”的效果。关键区别在于:它不生成多级折叠结构,也不支持按字段排序后再汇总,所有层级由 GROUP BY 字段顺序严格决定。
怎么写一个带两级小计的 WITH ROLLUP 查询?
假设有一张销售表 sales,含字段 region(大区)、city(城市)、amount(销售额),你想按大区→城市分组,并在每个大区后加城市小计、最后加总合计:
SELECT IFNULL(region, '总计') AS region, IFNULL(city, IF(region IS NULL, '', '小计')) AS city, SUM(amount) AS total FROM sales GROUP BY region, city WITH ROLLUP;
注意三点:
-
WITH ROLLUP必须紧跟在GROUP BY字段列表之后,不能加逗号或换行干扰 - MySQL 对
NULL的处理是核心机制:当某一级分组“上卷”时,对应字段值设为NULL(如城市小计行的city为NULL,总计行的region和city都为NULL) - 必须用
IFNULL()或CASE WHEN显式重命名NULL,否则结果里会看到一堆NULL,无法区分小计/总计
为什么 GROUP BY 字段顺序错了,小计就全乱了?
因为 WITH ROLLUP 的层级完全依赖 GROUP BY 的字段顺序:先按第一个字段分组,再在每个组内按第二个字段分组,依此类推;上卷也是从右往左逐级退。比如写成 GROUP BY city, region WITH ROLLUP,就会先按城市分组,再在每个城市内按大区分,最终得到的是“每个城市下的大区小计”,而不是你想要的“每个大区下的城市小计”。这和 Excel 中拖动字段到“行标签”区域的顺序一一对应。
把记录数组导出为带样式的 Excel(xlsx) 或带 BOM 的 CSV。支持列配置(表头/宽度/顺序)、表头冻结首行、斑马纹、布尔值转「是/否」、数组换行、CSV 中文防乱码。零依赖。触发词:导出 Excel、导出 CSV、记录转表格、列配置导出、数据导出、表格美化、JSON 转表格。
常见错误现象:
- 小计行数量远超预期(可能是字段顺序颠倒,导致上卷层级错位)
- 某一级小计消失(如缺了大区小计,只看到城市小计和总计,说明
region不在GROUP BY最左侧) - 同一城市出现在多个大区小计下(字段顺序反了,逻辑分组关系被破坏)
WITH ROLLUP 在其他数据库里能用吗?
不能直接用。WITH ROLLUP 是 MySQL 特有语法(MariaDB 兼容)。PostgreSQL 要用 GROUPING SETS,SQL Server 用 ROLLUP(无 WITH 关键字),Oracle 同样支持 ROLLUP 但语法细节不同。如果你写的 SQL 需要跨库运行,别硬套 WITH ROLLUP——要么改用标准 GROUPING SETS(需数据库版本支持),要么用 UNION ALL 拼接各层级查询(更通用但写法冗长)。
容易被忽略的一点:即使在 MySQL 里,WITH ROLLUP 与 ORDER BY 共存时,排序发生在分组和上卷之后,所以无法靠 ORDER BY 调整小计行的位置——小计永远紧贴其所属分组末尾,这是由执行逻辑决定的,不是显示问题。










