rollup和cube能生成多级汇总,但必须按业务层级由粗到细排列维度顺序,否则小计层级错乱;cube会爆炸式生成所有组合,宽表慎用;必须用grouping()函数区分汇总null与真实null,仅用is null会导致误判。

ROLLUP 和 CUBE 能直接生成多级汇总,但用错顺序或忽略 GROUPING() 就会把真实 NULL 当成小计,报表数据立刻出错。
ROLLUP 的层级路径完全由 GROUP BY 列顺序决定
ROLLUP 不是“自动按业务逻辑归并”,它严格从左到右逐级收口。写 GROUP BY region, province, city WITH ROLLUP 会产出:(region, province, city) → (region, province, NULL) → (region, NULL, NULL) → (NULL, NULL, NULL) 四层;但反过来写 GROUP BY city, province, region,第一层小计就变成“所有城市的合计”,中间彻底丢失 province 维度。
- 常见错误:把细粒度字段(如
product_id)放在前面,导致顶层只剩全量总计,业务上需要的“品类小计”直接消失 - 正确做法:按业务层级由粗到细排列,例如时间维度必须是
year, quarter, month,不是month, quarter, year - MySQL 8.0+ 和 SQL Server 支持原生
WITH ROLLUP;PostgreSQL 需用GROUPING SETS模拟
CUBE 会爆炸式生成所有组合,别在宽表上直接用
GROUP BY CUBE(a, b, c) 实际执行的是 8 个独立分组:(a,b,c)、(a,b,NULL)、(a,NULL,c)、(NULL,b,c)、(a,NULL,NULL)、(NULL,b,NULL)、(NULL,NULL,c)、(NULL,NULL,NULL)。这看起来灵活,但 5 个字段就是 32 行结果,扫描代价翻倍,聚合计算重复多次。
一款AI工具,主要用于在主代理响应前,并行运行Kimi K2.5和GPT 5.3 Codex,注入双方观点以增强认知多样性,适合需要提升相关任务效率的用户。
- 适用场景:明确需要任意切片钻取,比如 BI 工具后端要支持用户自由拖拽维度组合
- 不适用场景:常规年报/月报,尤其是字段含大量 NULL 或基数极高(如
user_id)时,CUBE 结果集可能膨胀数十倍 - PostgreSQL 不支持原生
WITH CUBE,得手写GROUPING SETS ((a,b,c),(a,b),(a,c),(b,c),(a),(b),(c),())
不用 GROUPING() 就没法安全过滤汇总行
ROLLUP/CUBE 输出的 NULL 是占位符,和原始数据里的 NULL 完全混在一起。仅靠 WHERE region IS NULL 会同时删掉“华东区小计”和“region 字段真为 NULL 的脏数据”。GROUPING(region) 才是唯一可靠判断方式:返回 1 表示该列为汇总生成的空值,返回 0 表示原始数据值。
- MySQL 中
GROUPING()在 8.0.12+ 才稳定支持;低版本只能靠GROUPING_ID()或手动 UNION - Oracle 推荐用
GROUPING_ID(a,b,c),结果值直接对应二进制掩码(如 3 = 0b011,表示 a 为明细,b/c 为汇总) - 千万别在
HAVING里用GROUPING()过滤——它只在 SELECT 和 ORDER BY 中有效,WHERE 阶段还没生成汇总行
真正麻烦的从来不是语法怎么写,而是你得先想清楚:这个报表到底需要哪几层小计?哪些组合有业务意义?哪些只是 CUBE 自动生成却没人看的噪音行?一旦漏掉 GROUPING() 判断,下游所有统计口径都会偏移。










