GROUP BY 的擴展運算符 CUBE、ROLLUP 與輔助函數 GROUPING() 能在單次查詢中產生多維度彙總,是報表開發的利器。
| 運算符 | 行為 | 輸出行數(以兩列為例) |
|---|---|---|
| CUBE | 所有列組合的聚合(全交叉) | (n+1)×(m+1) |
| ROLLUP | 層級聚合:按列順序由細到粗 | n×m + n + 1 |
CREATE TABLE dbo.PeopleInfo (
id INT IDENTITY(1,1) PRIMARY KEY,
[name] NCHAR(10),
numb NCHAR(10) NOT NULL,
phone NCHAR(10),
FenShu INT
);
INSERT INTO dbo.PeopleInfo([name],numb,phone,FenShu) VALUES
(N'李歡',N'3223',N'1365255',80),
(N'李歡',N'322123',N'1',90),
(N'李名',N'3213112352',N'13152',56),
(N'李名',N'32132312',N'13342563',60),
(N'王華',N'3223',N'1365255',80);
-- 普通分組
SELECT [name], numb, SUM(FenShu) AS Total
FROM dbo.PeopleInfo
GROUP BY [name], numb;
-- WITH CUBE
SELECT [name], numb, SUM(FenShu) AS Total
FROM dbo.PeopleInfo
GROUP BY [name], numb WITH CUBE;
結果差異:CUBE 額外產生 (李歡, NULL, 170)、(NULL, 3223, 160)、(NULL, NULL, 366) 等行,實現「按姓名彙總」「按工號彙總」「總計」三維度並存。
SELECT [name], numb, SUM(FenShu) AS Total
FROM dbo.PeopleInfo
GROUP BY [name], numb WITH ROLLUP;
關鍵規律:ROLLUP 只對 最右側列 逐級向上彙總。上例中 GROUP BY [name], numb 會產生:
[name], numb 分組小計[name] 分組小計(忽略 numb)不會 出現「按 numb 分組、忽略 name」的行。若交換列順序 GROUP BY numb, [name],層級遞歸方向隨之改變。
SELECT
[name],
numb,
SUM(FenShu) AS Total,
GROUPING([name]) AS IsNameTotal,
GROUPING(numb) AS IsNumbTotal
FROM dbo.PeopleInfo
GROUP BY [name], numb WITH ROLLUP;
1 = 該行由 CUBE/ROLLUP 產生(彙總行)0 = 原始明細行常用於報表前端區分「小計/總計」行以加粗或標註。
SQL Server 2008+ 支援 GROUPING SETS 精確控制輸出組合,避免 CUBE/ROLLUP 產生冗餘行:
GROUP BY GROUPING SETS (
([name], numb), -- 明細
([name]), -- 按姓名彙總
() -- 總計
)
CASE 輸出「總計」「小計」標籤。