🐷

【PostgreSQL】LAG 関数と LEAD 関数

に公開

準備

以下についてある程度理解しておくと良いかもです!
https://zenn.dev/codek2/articles/7d15f8ed965e9c

sales

id product sale_date amount
1 A 2024-02-01 1000
2 A 2024-02-02 1500
3 A 2024-02-03 1200
4 B 2024-02-01 2000
5 B 2024-02-02 1800
-- sales テーブルの作成
CREATE TABLE sales (
    id SERIAL PRIMARY KEY,
    product VARCHAR(10) NOT NULL,
    sale_date DATE NOT NULL,
    amount INT NOT NULL
);

-- データの挿入
INSERT INTO sales (product, sale_date, amount) VALUES
('A', '2024-02-01', 1000),
('A', '2024-02-02', 1500),
('A', '2024-02-03', 1200),
('B', '2024-02-01', 2000),
('B', '2024-02-02', 1800);

LAG関数

指定した行数(前の行)の値を取得

LEAD関数

指定した行数(後の行)の値を取得

基本構文

LAG(列名, [n], [デフォルト値]) OVER (PARTITION BY 列名 ORDER BY 列名)
LEAD(列名, [n], [デフォルト値]) OVER (PARTITION BY 列名 ORDER BY 列名)
項目 説明
列名 取得したい値の列名
n(オプション) 何行前(後)の値を取るか(省略時は 1)
デフォルト値(オプション) 取得できない場合の代替値(省略時は NULL)
PARTITION BY グループごとに処理する場合に指定(省略可)
ORDER BY 並び順を指定(必須)

使用例

LAG関数:商品ごとの1行前の行の売上を取得

SELECT product, sale_date, amount, 
    LAG(amount, 1, 0) OVER (PARTITION BY product ORDER BY sale_date) AS previous_amount
FROM sales;

LAG(amount, 1, 0)
  • 1行前の amount を取得
  • 前のデータが取得出来ない場合は0を表示

LEAD関数:商品ごとの1行後の売上を取得

SELECT 
    product, 
    sale_date, 
    amount, 
    LEAD(amount, 1, 0) OVER (PARTITION BY product ORDER BY sale_date) AS next_amount
FROM sales;

LEAD(amount, 1, 0)
  • 1行後の amount を取得
  • 後のデータが取得出来ない場合は0を表示

応用例

前回との差分(今回の売上-前回の売上)を計算

SELECT 
    product, 
    sale_date, 
    amount, 
    amount - LAG(amount, 1, 0) OVER (PARTITION BY product ORDER BY sale_date) AS difference
FROM sales;

Udemyで講座を公開中!
https://zenn.dev/codek2/articles/e9e44f3e0023fb

X(旧Twitter)
https://twitter.com/kunchan2_

Zenn 本
https://zenn.dev/codek2?tab=books

Youtube
https://www.youtube.com/@codek2_studio

Discussion