當 GROUP BY 指定兩個以上欄位時,資料庫會依「先後順序」進行遞迴分組。本文透過實測資料與圖解,詳細說明多鍵分組的運作機制與結果差異。
CREATE TABLE test (
a VARCHAR(20),
b VARCHAR(20),
c VARCHAR(20)
);
INSERT INTO test VALUES
('1','a','甲'), ('1','a','甲'), ('1','a','甲'), ('1','a','甲'),
('1','a','乙'),
('1','b','乙'), ('1','b','乙'), ('1','b','乙');
原始資料 (8 筆):
+---+---+---+ | a | b | c | +---+---+---+ | 1 | a | 甲 | | 1 | a | 甲 | | 1 | a | 甲 | | 1 | a | 甲 | | 1 | a | 乙 | | 1 | b | 乙 | | 1 | b | 乙 | | 1 | b | 乙 | +---+---+---+
GROUP BY b:a 群組 5 筆、b 群組 3 筆GROUP BY c:甲 群組 4 筆、乙 群組 4 筆SELECT COUNT(a), b, c FROM test GROUP BY b, c;
結果:
+-----------+---+---+ | COUNT(a) | b | c | +-----------+---+---+ | 4 | a | 甲 | | 1 | a | 乙 | | 3 | b | 乙 | +-----------+---+---+
SELECT COUNT(a), b, c FROM test GROUP BY c, b;
結果:
+-----------+---+---+ | COUNT(a) | b | c | +-----------+---+---+ | 4 | a | 甲 | | 1 | a | 乙 | | 3 | b | 乙 | +-----------+---+---+
GROUP BY b, c 執行過程:
b 切分 → 群組 1 (b='a',第 1-5 筆)、群組 2 (b='b',第 6-8 筆)c 細分
結論:GROUP BY b, c 與 GROUP BY c, b 最終聚合結果相同 (相同鍵值組合、相同計數),但輸出順序可能不同 (視 DBMS 排序實作)。
| 場景 | GROUP BY 組合 | 說明 |
|---|---|---|
| 銷售報表 | region, product_category, month | 依區域→產品類→月份層層匯總 |
| 網站流量分析 | date, channel, device | 依日期→管道→裝置分組 |
| 庫存管理 | warehouse, sku, batch | 依倉庫→SKU→批次追蹤 |
COALESCE(col, 'UNKNOWN')。INDEX idx_b_c (b, c)。HAVING COUNT(*) > 1 可過濾低頻群組。# 一次產生多層級彙總 SELECT b, c, COUNT(*) FROM test GROUP BY ROLLUP (b, c); # 等同於: GROUP BY b, c + GROUP BY b + GROUP BY ()
掌握多欄位分組邏輯,能撰寫出精準、高效的多維度統計查詢。