窗口函數 (SQL Window Functions)

窗口函數 (Window Functions) 又稱為分析函數 (Analytic Functions),它可以對一組相關的資料列進行運算,而不會像 GROUP BY 那樣將多列合併成一列。

窗口函數最大的特點是:保留原本的資料列,同時在每一列上計算出彙總或排序的結果。

窗口函數語法

function_name(expression) OVER (
    [PARTITION BY column_name(s)]
    [ORDER BY column_name(s)]
    [frame_clause]
)
  • PARTITION BY: 將資料分組,每組獨立計算
  • ORDER BY: 決定計算時資料的排列順序
  • frame_clause: 定義計算的資料範圍 (窗口框架)

OVER 子句

OVER 子句是窗口函數的核心,用來定義「窗口」的範圍。

-- 空的 OVER() 代表整個結果集為一個窗口
SELECT name, salary, SUM(salary) OVER() AS total
FROM employees;

常見的窗口函數

排名函數

函數說明
ROW_NUMBER()為每列指派唯一的連續編號
RANK()排名,相同值同排名,之後跳號
DENSE_RANK()密集排名,相同值同排名,之後不跳號
NTILE(n)將資料平均分成 n 組

彙總函數

一般的彙總函數加上 OVER 子句就成為窗口函數:

函數說明
SUM()累計加總
AVG()累計平均
COUNT()累計計數
MIN()累計最小值
MAX()累計最大值

位移函數

函數說明
LAG(column, n)取前 n 列的值
LEAD(column, n)取後 n 列的值
FIRST_VALUE(column)取窗口中第一列的值
LAST_VALUE(column)取窗口中最後一列的值
NTH_VALUE(column, n)取窗口中第 n 列的值

窗口函數用法範例 (Example)

假設我們有一個 sales 資料表:

MonthRegionAmount
1北部1000
2北部1500
1南部800
2南部1200

累計加總

SELECT
    Month, Region, Amount,
    SUM(Amount) OVER (PARTITION BY Region ORDER BY Month) AS RunningTotal
FROM sales;

查詢結果:

MonthRegionAmountRunningTotal
1北部10001000
2北部15002500
1南部800800
2南部12002000

與前期比較

使用 LAG() 函數取得上一期資料進行比較:

SELECT
    Month, Region, Amount,
    LAG(Amount, 1) OVER (PARTITION BY Region ORDER BY Month) AS PrevAmount,
    Amount - LAG(Amount, 1) OVER (PARTITION BY Region ORDER BY Month) AS Growth
FROM sales;

窗口函數 vs GROUP BY

特性窗口函數GROUP BY
資料列數量保留所有原始資料列每組彙總成一列
細節資料可同時顯示細節與彙總只能顯示彙總結果
排名功能支援不支援