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 数据:

regionproductsales
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;

结果:

regionproducttotal_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;

结果

regionproducttotal_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;

结果

regionproducttotal_sales
North NULL 300
South NULL 400

方案③:(product) → 只按 product 分组(产品小计)

-- 相当于
SELECT NULL AS region, product, SUM(sales) AS total_sales
FROM sales
GROUP BY product;

结果

regionproducttotal_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;

结果

regionproducttotal_sales
NULL NULL 700

最后:把所有方案的结果“合并”起来!

把上面 4 个方案的 4 + 2 + 2 + 1 = 9 行 合并,并按 ORDER BY region, product 排序:

regionproducttotal_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 方案① 明细
posted @ 2025-11-19 14:30  chao_xiong  阅读(12)  评论(0)    收藏  举报