使用ROLLUP、CUBE、GROUPING SETS或UNION可实现SQL多级统计:ROLLUP按层级生成小计和总计,如年月销售汇总;CUBE生成所有分组组合,适用于交叉分析;GROUPING SETS自定义分组级别,灵活指定汇总维度;UNION ALL合并多个独立分组查询,兼容性强且便于标注层级。不同方法适用于不同数据库与场景,结合GROUPING()函数可区分汇总行。
在 SQL 中实现多级统计,通常是指对数据进行多层次的分组汇总,比如按地区、部门、年月逐层统计销售额。这类需求可以通过 GROUP BY 配合一些扩展语法来实现,常见的方法包括使用 ROLLUP、CUBE 或 GROUPING SETS,也可以通过子查询或 UNION 手动构造多级汇总。
1. 使用 GROUP BY ROLLUP 实现层级汇总
ROLLUP 可以生成从最细粒度到最高层级的累计汇总行,适合有明确层级关系的字段(如 年 → 月)。
示例:按年、月统计订单金额,并包含每月小计和年度总计
SELECT year, month, SUM(amount) AS total_amount FROM sales GROUP BY ROLLUP (year, month);
结果会包含:
- 每一年每一月的数据
- 每一年的合计(month 为 NULL)
- 所有年份的总合计(year 和 month 均为 NULL)
2. 使用 GROUP BY CUBE 生成所有组合
CUBE 会生成所有可能的分组组合,适用于需要交叉分析的场景。
示例:按产品类别和区域统计销量,包含所有组合(类总计、区总计、总合计等)
SELECT category, region, SUM(sales) AS total_sales FROM sales_data GROUP BY CUBE (category, region);
输出包括:
- 每个 category + region 的明细
- 每个 category 的汇总(region 为 NULL)
- 每个 region 的汇总(category 为 NULL)
- 整体总和(都为 NULL)
3. 使用 GROUPING SETS 自定义汇总级别
GROUPING SETS 允许你精确指定想要的分组方式,灵活性更高。
示例:只想看按年汇总、按月汇总和总体总和,不要年月组合的交叉项
SELECT year, month, SUM(amount) AS total FROM sales GROUP BY GROUPING SETS ((year), (month), ());
这将返回:
- 每年的总金额
- 每月的总金额
- 全部总额
4. 使用 UNION 联合多个分组查询
如果数据库不支持 ROLLUP 或 CUBE,或者你需要更复杂的逻辑控制,可以用 UNION ALL 拼接不同层级的查询。
示例:分别查出按部门、按岗位、以及公司总人数
SELECT 'dept' AS level, dept AS group_name, COUNT(*) AS cnt FROM employees GROUP BY dept UNION ALL SELECT 'job', job, COUNT(*) FROM employees GROUP BY job UNION ALL SELECT 'total', 'all', COUNT(*) FROM employees;
这种方式便于添加标签说明统计层级,也容易做格式化输出。
基本上就这些。根据你的数据库类型(如 MySQL、PostgreSQL、SQL Server)和具体需求选择合适的方法。ROLLUP 和 CUBE 简洁高效,GROUPING SETS 更灵活,UNION 则兼容性强、控制精细。注意配合 GROUPING() 函数或判断 NULL 来区分汇总行和原始数据行,避免混淆。