聚合函數(Aggregate Functions)又稱群組函數,用於對一組資料列進行計算並返回單一結果值。Oracle 提供豐富的聚合函數,廣泛應用於統計報表、資料分析、商業智慧等場景。
| 函數 | 功能說明 | 適用資料型別 |
|---|---|---|
COUNT | 計算行數或非空值個數 | 所有型別 |
SUM | 求和 | 數值型別 |
AVG | 計算平均值 | 數值型別 |
MAX | 求最大值 | 數值、字串、日期 |
MIN | 求最小值 | 數值、字串、日期 |
STDDEV | 標準差 | 數值型別 |
VARIANCE | 變異數 | 數值型別 |
所有聚合函數(COUNT(*) 除外)預設會忽略 NULL 值。這是最常見的誤區來源。
-- EMP 表共 14 筆資料,MGR 欄位有 1 筆 NULL(KING 社長無主管)
SELECT COUNT(*) AS total_rows, -- 14,計算所有行
COUNT(mgr) AS mgr_count, -- 13,忽略 NULL
COUNT(comm) AS comm_count -- 4,只有 4 位業務有提成
FROM emp;
TOTAL_ROWS MGR_COUNT COMM_COUNT
---------- --------- ----------
14 13 4
SELECT SUM(comm), AVG(comm), MAX(comm), MIN(comm)
FROM emp;
-- 皆自動忽略 COMM 為 NULL 的 10 筆資料
在聚合函數中使用 DISTINCT 可排除重複值,僅統計唯一值:
-- 錯誤寫法:重複計算部門編號
SELECT COUNT(deptno) FROM emp; -- 14
-- 正確寫法:統計唯一部門數
SELECT COUNT(DISTINCT deptno) FROM emp; -- 3
-- 不同薪資等級的平均薪資(去除相同薪資值)
SELECT AVG(DISTINCT sal) FROM emp;
-- 不同職稱的最高薪資
SELECT MAX(DISTINCT sal) KEEP (DENSE_RANK FIRST ORDER BY job) FROM emp; -- 進階用法
SELECT deptno,
COUNT(*) AS emp_count,
AVG(sal) AS avg_sal,
MAX(sal) AS max_sal,
MIN(sal) AS min_sal,
SUM(sal) AS total_sal
FROM emp
GROUP BY deptno
ORDER BY deptno;
-- 僅顯示平均薪資超過 2000 的部門
SELECT deptno, AVG(sal) AS avg_sal
FROM emp
GROUP BY deptno
HAVING AVG(sal) > 2000;
-- 將 NULL 提成視為 0 計算平均提成
SELECT AVG(NVL(comm, 0)) AS avg_comm_with_zero
FROM emp;
-- 結果會包含所有 14 位員工,平均值較低
| 寫法 | 統計對象 | 包含 NULL | 去重 |
|---|---|---|---|
COUNT(*) | 所有行 | 是 | 否 |
COUNT(expr) | expr 非 NULL 的行 | 否 | 否 |
COUNT(DISTINCT expr) | expr 唯一非 NULL 值 | 否 | 是 |
| 函數 | 數值 | 字串 | 日期 | 備註 |
|---|---|---|---|---|
| COUNT | ✓ | ✓ | ✓ | 通用 |
| MAX/MIN | ✓ | ✓ | ✓ | 字串按字典序、日期按時間序 |
| SUM/AVG | ✓ | ✗ | ✗ | 僅數值 |
| STDDEV/VARIANCE | ✓ | ✗ | ✗ | 僅數值 |
APPROX_COUNT_DISTINCT(12c+)獲得近似去重計數,大幅提升效能PARALLEL Hint 加速掌握 Oracle 聚合函數的核心在於理解「自動忽略 NULL」與「DISTINCT 去重」兩大特性。結合 GROUP BY、HAVING 子句,即可構建強大的統計分析查詢。實務上需特別注意 COUNT(*) 與 COUNT(col) 的語意差異,以及 NULL 值對 AVG、SUM 等計算結果的影響,避免業務邏輯錯誤。