一、什么是GROUPING SETS?
GROUPING SETS是SQL標準中的多維聚合運算符,允許在單個查詢中實現多維度組合的分組統計。相較于傳統UNION ALL方案,性能可提升3-10倍(TPC-DS基準測試)。
二、核心語法解析
SELECT column1, column2,SUM(metric)
FROM table
GROUP BY GROUPING SETS ((column1), -- 維度1單獨分組(column2), -- 維度2單獨分組(column1, column2), -- 維度組合() -- 總計行
)
三、實戰場景演示
場景1:電商銷售分析(時間+品類)
SELECT COALESCE(time_period, '總計') AS time,COALESCE(category, '全品類') AS category,SUM(sales) AS total_sales
FROM sales_data
GROUP BY GROUPING SETS ((time_period, category), -- 各時段各品類(time_period), -- 各時段匯總(category), -- 各品類匯總() -- 全局總計
)
ORDER BY time NULLS LAST, category NULLS LAST;
time | category | total_sales
2023-Q1 | 手機 | 1200000
2023-Q1 | 電腦 | 980000
2023-Q1 | 全品類 | 2180000 -- 時段小計
全時段 | 手機 | 4500000 -- 品類匯總
全時段 | 電腦 | 3200000
總計 | 全品類 | 7700000 -- 全局總計
場景2:網絡流量監控(應用+地區)
SELECT app_type,region,COUNT(DISTINCT user_id) AS uv,SUM(data_usage) / 1024 AS data_usage_gb
FROM network_logs
GROUP BY GROUPING SETS ((app_type, region), -- 應用+地區組合(app_type), -- 應用維度匯總(region) -- 地區維度匯總
)
四、進階使用技巧
1. 與GROUPING函數配合
SELECT CASE GROUPING(department) WHEN 1 THEN '所有部門' ELSE department END AS dept,CASE GROUPING(job_role) WHEN 1 THEN '全部職位' ELSE job_role END AS role,AVG(salary) AS avg_salary
FROM employee
GROUP BY GROUPING SETS ((department, job_role),(department),(job_role)
)
2. 分層統計模板
-- 生成國家-省份-城市三級統計
GROUPING SETS ((country, province, city),(country, province),(country),()
)
五、避坑指南
1. 字段引用陷阱
錯誤寫法:
SELECT SUM(amount)/COUNT(*) AS avg_amount -- 錯誤!COUNT(*)包含空分組
FROM orders
GROUP BY GROUPING SETS ((region), ())
正確方案:
SELECT SUM(amount) / NULLIF(COUNT(region), 0) AS avg_amount
2. 排序邏輯優化
ORDER BY GROUPING(department) ASC, -- 匯總行置后department NULLS LAST
3. 空值處理方案
SELECTCOALESCE(region, '全國') AS region,CASE WHEN GROUPING(month) = 1 THEN '年度匯總' ELSE TO_CHAR(month, 'YYYY-MM') END AS month
。
4.建議
- 優先使用GROUP BY ()顯式聲明總計行
- 所有度量字段必須使用聚合函數