| 特性 | ROLLUP | CUBE |
|---|---|---|
| 彙總層級數 (n 個欄位) | n + 1 | 2^n |
| 彙總維度 | 階層式:由細到粗 (右到左) | 所有維度組合排列 |
| 適用場景 | 層次式報表 (年→季→月、國→省→市) | 交叉報表、多維度分析 (OLAP) |
| 結果排序 | 依 GROUP BY 順序自然排序 | 需額外 ORDER BY |
GROUP BY ROLLUP (col1, col2, ..., coln)
SELECT d.dname, e.job, TO_CHAR(e.hiredate, 'YYYY') hire_year, SUM(e.sal) total_sal FROM emp e JOIN dept d ON e.deptno = d.deptno GROUP BY ROLLUP (d.dname, e.job, TO_CHAR(e.hiredate, 'YYYY')) ORDER BY d.dname, e.job, hire_year;
彙總層級 (3+1=4 層):
僅對部分欄位做階層彙總,其餘維度保持分組。
GROUP BY CUBE (col1, col2, ..., coln)
對 n 個欄位的所有子集合執行 GROUP BY:
GROUP BY CUBE (d.dname, e.job, TO_CHAR(e.hiredate, 'YYYY'))
產生:(d,j,y), (d,j), (d,y), (j,y), (d), (j), (y), () — 8 組彙總。
SELECT d.dname, e.job, GROUPING(d.dname) AS is_dname_total, GROUPING(e.job) AS is_job_total, GROUPING_ID(d.dname, e.job) AS grouping_id, SUM(e.sal) total_sal FROM emp e JOIN dept d ON e.deptno = d.deptno GROUP BY CUBE (d.dname, e.job);
| GROUPING_ID | 二進位 | 含義 |
|---|---|---|
| 0 | 00 | 明細列 (dname, job 皆非彙總) |
| 1 | 01 | job 彙總列 (dname 明細, job 小計) |
| 2 | 10 | dname 彙總列 (dname 小計, job 明細) |
| 3 | 11 | 總計列 (dname, job 皆彙總) |
SELECT * FROM (
SELECT deptno, job, sal FROM emp
)
PIVOT (
SUM(sal) FOR job IN (
'CLERK' AS clerk_sal,
'MANAGER' AS mgr_sal,
'ANALYST' AS analyst_sal,
'SALESMAN' AS sales_sal,
'PRESIDENT' AS pres_sal
)
)
ORDER BY deptno;
SELECT * FROM ( SELECT deptno, job, sal FROM emp ) PIVOT XML ( SUM(sal) FOR job IN (ANY) ) ORDER BY deptno;
建議 說明 優先使用 ROLLUP/CUBE 單次掃描完成多層彙總,避免多次 UNION ALL 掃描 配合 GROUPING_ID 應用層易於識別彙總層級,生成階層式報表 UI 大表考慮物化視圖 預計算 ROLLUP/CUBE 結果,查詢時直接讀取 PIVOT 替代 CASE 聚合 語法更簡潔,優化器內部同樣單次掃描 注意 NULL 語意 彙總列維度為 NULL,GROUPING 函數必須區分 總結
ROLLUP適合階層式報表 (年→季→月),CUBE適合多維度交叉分析 (OLAP 切片塊)。兩者皆為GROUP BY擴展,單次掃描產生多層彙總,配合GROUPING/GROUPING_ID識別彙總列,再搭配PIVOT/UNPIVOT完成行列轉換,構成 Oracle 進階分析 SQL 的核心工具箱。