9.1 、GROUPING SETS 多方案分组
1、GROUPING SETS
用于在单个查询中同时按多种不同的分组方式,并将结果合并成一张表。避免写多个 UNION ALL 查询。
- 它被 PostgreSQL、SQL Server、Oracle、Snowflake 等主流数据库支持(MySQL 不支持)。
- 指定多个“分组方案”,SQL 引擎会分别按每个方案分组,并将结果合并成一张表。
SELECT col1, col2, aggregate_function(...) FROM table GROUP BY GROUPING SETS ( -- 每个括号 () 表示一种分组方式。 (col1, col2), -- 方案1:按 col1 和 col2 分组 (col1), -- 方案2:只按 col1 分组 (col2), -- 方案3:只按 col2 分组 () -- 方案4:不分组(全局汇总)空括号 () 表示全表聚合(总计)。 );
表 sales 数据:
| region | product | sales |
|---|---|---|
| North | A | 100 |
| North | B | 200 |
| South | A | 150 |
| South | B | 250 |
的
SELECT region, product, SUM(sales) AS total_sales FROM sales GROUP BY GROUPING SETS ( -- 分别按这4种方式分组,然后把结果“拼”在一起。 (region, product), -- 明细 (region), -- 区域小计 (product), -- 产品小计 () -- 总计 ) ORDER BY region, product;
结果:
| region | product | total_sales | 说明 |
|---|---|---|---|
| NULL | NULL | 700 | 全局总计(()) |
| NULL | A | 250 | 产品 A 小计 |
| NULL | B | 450 | 产品 B 小计 |
| North | NULL | 300 | North 区域小计 |
| South | NULL | 400 | South 区域小计 |
| North | A | 100 | 明细 |
| North | B | 200 | 明细 |
| South | A | 150 | 明细 |
| South | B | 250 | 明细 |
注意:未参与当前分组的列显示为 NULL,这是关键标识!
NULL不是原始数据中的空值,而是表示“这个维度在这个分组方案中未被使用”。
解析:
方案①:(region, product) → 按两个字段一起分组(明细)
-- 相当于 SELECT region, product, SUM(sales) AS total_sales FROM sales GROUP BY region, product;
结果
| region | product | total_sales |
|---|---|---|
| North | A | 100 |
| North | B | 200 |
| South | A | 150 |
| South | B | 250 |
方案②:(region) → 只按 region 分组(区域小计)
--相当于 SELECT region, NULL AS product, SUM(sales) AS total_sales FROM sales GROUP BY region;
结果
| region | product | total_sales |
|---|---|---|
| North | NULL | 300 |
| South | NULL | 400 |
方案③:(product) → 只按 product 分组(产品小计)
-- 相当于 SELECT NULL AS region, product, SUM(sales) AS total_sales FROM sales GROUP BY product;
结果
| region | product | total_sales |
|---|---|---|
| NULL | A | 250 |
| NULL | B | 450 |
方案④:() → 空分组(全局总计),
全表汇总:100 + 200 + 150 + 250 = 700
-- 相当于 SELECT NULL AS region, NULL AS product, SUM(sales) AS total_sales FROM sales;
结果
| region | product | total_sales |
|---|---|---|
| NULL | NULL | 700 |
最后:把所有方案的结果“合并”起来!
把上面 4 个方案的 4 + 2 + 2 + 1 = 9 行 合并,并按 ORDER BY region, product 排序:
| region | product | total_sales | 来源 |
|---|---|---|---|
| NULL | NULL | 700 | 方案④ 总计 |
| NULL | A | 250 | 方案③ 产品A小计 |
| NULL | B | 450 | 方案③ 产品B小计 |
| North | NULL | 300 | 方案② North小计 |
| North | A | 100 | 方案① 明细 |
| North | B | 200 | 方案① 明细 |
| South | NULL | 400 | 方案② South小计 |
| South | A | 150 | 方案① 明细 |
| South | B | 250 | 方案① 明细 |
本文来自博客园,作者:chao_xiong,转载请注明原文链接:https://www.cnblogs.com/chao-xiong/p/19242344

浙公网安备 33010602011771号