DB2 自 V6 引入 OLAP 函數,擴展關聯模型使其理解「行集合內的順序」。按功能分為:
RANK、DENSE_RANK、ROW_NUMBERSUM/AVG/COUNT/MAX/MIN... OVER(),分「報表函數」(無 ORDER BY)與「累加函數」(有 ORDER BY)PERCENT_RANK、CUME_DIST、NTILE 等SELECT empnum, dept, salary,
RANK() OVER (PARTITION BY dept ORDER BY salary DESC NULLS LAST) AS rnk,
DENSE_RANK() OVER (PARTITION BY dept ORDER BY salary DESC NULLS LAST) AS drnk,
ROW_NUMBER() OVER (PARTITION BY dept ORDER BY salary DESC NULLS LAST) AS rn
FROM emptab;
| 函數 | 相同值處理 | 下一名次 | 典型用途 |
|---|---|---|---|
| RANK | 同名次(奧林匹克制) | 跳過數量(1,2,2,4) | 排名報表、並列名次 |
| DENSE_RANK | 同名次 | 連續遞增(1,2,2,3) | 連續分級、分頁 |
| ROW_NUMBER | 任意排序(非確定性) | 連續 1,2,3,4 | 去重、分頁、取 Top-N |
NULLS LAST(V7+)將 NULL 排最後,避免 NULL 薪水佔據第一名。V6 可用 CASE WHEN salary IS NULL THEN 1 ELSE 0 END, salary DESC 模擬。
SELECT dept, salary,
SUM(salary) OVER (PARTITION BY dept) AS dept_sum,
AVG(salary) OVER (PARTITION BY dept) AS dept_avg,
COUNT(*) OVER (PARTITION BY dept) AS dept_cnt,
MAX(salary) OVER (PARTITION BY dept) AS dept_max
FROM emptab;
等價於 GROUP BY dept 再 JOIN 回原表,但語法更簡潔、執行計畫更優。百分比計算 一行搞定:DECIMAL(salary,10,2) / SUM(salary) OVER (PARTITION BY dept) AS pct
SELECT date, sales,
SUM(sales) OVER (ORDER BY date) AS ytd_sales,
COUNT(*) OVER (ORDER BY date) AS day_cnt
FROM sales
WHERE YEAR(date) = 2000;
結果:第 1 行 = 1 月銷售,第 2 行 = 1+2 月累計... 實現 Year-To-Date 報表零自連接。
SUM(sales) OVER (PARTITION BY YEAR(date) ORDER BY MONTH(date)) AS ytd_sales
跨年自動歸零,OVER 子句支援運算式分區/排序,極度靈活。
年銷售總額累加:
SELECT YEAR(date) AS yr, SUM(sales) AS yr_sum,
SUM(SUM(sales)) OVER (ORDER BY YEAR(date)) AS cum_yr_sum
FROM sales
WHERE YEAR(date) >= 1995
GROUP BY YEAR(date);
處理順序:FROM → WHERE → GROUP BY → HAVING → SELECT(含 OLAP)。因此 OLAP 函數可引用 GROUP BY 聚合結果,但不可直接用於 WHERE/HAVING。
WITH ranked_years AS (
SELECT YEAR(date) AS yr, SUM(sales) AS yr_sum,
RANK() OVER (ORDER BY SUM(sales) DESC) AS rnk
FROM sales
GROUP BY YEAR(date)
)
SELECT yr, yr_sum, rnk
FROM ranked_years
WHERE rnk <= 3;
同理可求中位數、百分位:WHERE rnk IN (FLOOR((cnt+1)/2), CEIL((cnt+1)/2))。
PARTITION BY、ORDER BY 欄位建立複合索引可避免排序溢寫磁碟。RANGE UNBOUNDED PRECEDING(累加),可顯式指定 ROWS BETWEEN 3 PRECEDING AND CURRENT ROW 實現移動平均。LAG/LEAD/FIRST_VALUE/LAST_VALUE、V11.1 RATIO_TO_REPORT,持續跟進新函數。OLAP 函數將複雜的自連接、子查詢、臨時表邏輯轉化為宣告式單查詢,是 SQL 開發者從「寫查詢」進階到「設計資料流」的關鍵槓桿。