LAG() 與 LEAD() 函數

LAG() 和 LEAD() 是窗口函數中的位移函數,用來存取同一結果集中「前幾列」或「後幾列」的資料,常用於比較相鄰資料列之間的差異。

  • LAG(): 取得「前面」第 N 列的值
  • LEAD(): 取得「後面」第 N 列的值

LAG 語法

LAG(column, offset, default_value) OVER (
    [PARTITION BY column_name(s)]
    ORDER BY column_name(s)
)
  • column: 要取值的欄位
  • offset: 往前幾列(預設為 1)
  • default_value: 當沒有前一列時的預設值(選填)

LEAD 語法

LEAD(column, offset, default_value) OVER (
    [PARTITION BY column_name(s)]
    ORDER BY column_name(s)
)

參數與 LAG() 相同,但方向是往後取值。

LAG 基本用法 (Example)

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

MonthSales
11000
21200
31100
41500

使用 LAG() 取得上個月的銷售額來計算成長:

SELECT 
    Month,
    Sales,
    LAG(Sales, 1) OVER (ORDER BY Month) AS prev_sales,
    Sales - LAG(Sales, 1) OVER (ORDER BY Month) AS growth
FROM monthly_sales;

查詢結果:

MonthSalesprev_salesgrowth
11000NULLNULL
212001000200
311001200-100
415001100400

第一列沒有「前一列」,所以 prev_sales 是 NULL。

設定預設值

可以指定第三個參數作為沒有資料時的預設值:

SELECT 
    Month,
    Sales,
    LAG(Sales, 1, 0) OVER (ORDER BY Month) AS prev_sales
FROM monthly_sales;

這樣第一列的 prev_sales 會是 0 而非 NULL。

LEAD 用法 (Example)

使用 LEAD() 取得下個月的銷售額:

SELECT 
    Month,
    Sales,
    LEAD(Sales, 1) OVER (ORDER BY Month) AS next_sales
FROM monthly_sales;

查詢結果:

MonthSalesnext_sales
110001200
212001100
311001500
41500NULL

取得前後 N 列

offset 參數可以指定往前或往後幾列:

SELECT 
    Month,
    Sales,
    LAG(Sales, 2) OVER (ORDER BY Month) AS sales_2_months_ago,
    LEAD(Sales, 2) OVER (ORDER BY Month) AS sales_in_2_months
FROM monthly_sales;

搭配 PARTITION BY 使用

在各分組內分別計算:

SELECT 
    Region,
    Month,
    Sales,
    LAG(Sales, 1) OVER (PARTITION BY Region ORDER BY Month) AS prev_sales
FROM regional_sales;

這樣每個地區的「上個月」會各自獨立計算。

實務應用:計算成長率

SELECT 
    Month,
    Sales,
    LAG(Sales, 1) OVER (ORDER BY Month) AS prev_sales,
    ROUND((Sales - LAG(Sales, 1) OVER (ORDER BY Month)) * 100.0 
          / LAG(Sales, 1) OVER (ORDER BY Month), 2) AS growth_rate
FROM monthly_sales;

實務應用:年增率 (YoY)

比較與去年同期的差異:

SELECT 
    Year,
    Month,
    Sales,
    LAG(Sales, 12) OVER (ORDER BY Year, Month) AS sales_last_year,
    Sales - LAG(Sales, 12) OVER (ORDER BY Year, Month) AS yoy_growth
FROM monthly_sales;