在 Oracle 文檔中,「分組函數」與「聚合函數」實為同義詞,指對一組資料列運算返回單一值的函數。本文系統整理其類型、查詢執行順序與實戰技巧。
理解執行順序是編寫正確分組查詢的關鍵:
| 函數 | 功能 | 適用資料型別 | 備註 |
|---|---|---|---|
AVG | 平均值 | 數值 | |
COUNT | 計數 | 所有 | 三種寫法見下表 |
MAX | 最大值 | 數值、字串、日期 | |
MIN | 最小值 | 數值、字串、日期 | |
SUM | 合計 | 數值 | |
STDDEV | 標準差 | 數值 | 樣本標準差 |
VARIANCE | 變異數 | 數值 | 樣本變異數 |
| 語法 | 說明 | 包含 NULL | 去重 |
|---|---|---|---|
COUNT(*) | 返回查詢結果總行數 | 是 | 否 |
COUNT(expr) | 統計 expr 非 NULL 的行數 | 否 | 否 |
COUNT(DISTINCT expr) | 統計 expr 唯一非 NULL 個數 | 否 | 是 |
若需將 NULL 納入計算,請使用 NVL、NVL2 或 COALESCE 轉換:
-- 計算平均提成,將 NULL 視為 0
SELECT AVG(NVL(comm, 0)) FROM emp;
DISTINCT:僅考慮不重複值ALL:考慮所有值(含重複),為預設值,通常省略可接受 CHAR、VARCHAR2、NUMBER、DATE 型別參數。
使用 GROUP BY 時,Oracle 預隱式以升序排序結果集。需自訂排序請明確使用 ORDER BY。
| 函數 | 數值 | 字串 | 日期 |
|---|---|---|---|
| MIN、MAX | ✓ | ✓ | ✓ |
| AVG、SUM、VARIANCE、STDDEV | ✓ | ✗ | ✗ |
| COUNT | ✓ | ✓ | ✓ |
-- 需求:統計各部門平均薪資,但將 NULL 薪資視為 0 參與計算
SELECT deptno, AVG(NVL(sal, 0)) AS avg_sal
FROM emp
GROUP BY deptno;
-- 需求:統計有提成員工比例
SELECT deptno,
COUNT(comm) * 100.0 / COUNT(*) AS comm_pct
FROM emp
GROUP BY deptno;
-- ROLLUP:層級彙總(部門 → 總計)
SELECT deptno, job, COUNT(*), SUM(sal)
FROM emp
GROUP BY ROLLUP(deptno, job);
-- CUBE:所有維度組合彙總
SELECT deptno, job, COUNT(*), SUM(sal)
FROM emp
GROUP BY CUBE(deptno, job);
-- 僅需部門彙總與總計,不需職稱彙總
SELECT deptno, job, COUNT(*), SUM(sal)
FROM emp
GROUP BY GROUPING SETS((deptno, job), (deptno), ());
| 錯誤寫法 | 問題 | 正確寫法 |
|---|---|---|
| SELECT deptno, ename FROM emp GROUP BY deptno | 非聚合欄位未出現在 GROUP BY | SELECT deptno, MAX(ename) 或加入 GROUP BY ename |
| WHERE AVG(sal) > 2000 | 聚合函數不可用於 WHERE | HAVING AVG(sal) > 2000 |
| SELECT COUNT(*) FROM emp WHERE sal = AVG(sal) | 無法在同層級 WHERE 中引用聚合 | 使用子查詢或窗口函數 |
Oracle 分組函數是資料分析的基石。掌握七大核心函數特性、執行順序邏輯、NULL 處理機制與進階彙總語法(ROLLUP/CUBE/GROUPING SETS),能讓你高效完成從簡單統計到複雜多維分析的各類需求。實務中務必區分 WHERE(列過濾)與 HAVING(組過濾)的適用時機,避免語法錯誤與邏輯偏差。