$ man lag
LAG / LEAD
ウィンドウ関数並べた中で、1 つ前(LAG)や 1 つ後ろ(LEAD)の行の値を持ってくる。前月比などに使う。
呼び出しの形
LAG(式) OVER (ORDER BY 式) LAG(式, n, 既定値) OVER (ORDER BY 式) LEAD(式) OVER (ORDER BY 式)
つまずきやすいところ
最初の行(
LEADなら最後の行)は必ず NULLです。引き算に使うなら第 3 引数かCOALESCEで埋めてください。ORDER BYが「前」「後ろ」の意味を決めます。並び順を書かないと結果に意味がありません。PARTITION BYを書き忘れると、区切りをまたいで前の行を拾ってしまいます(顧客 A の最初の行が、顧客 B の最後の行を「前」として拾う)。
実行例
結果は実際に流したものです。同じ SQL を 自由に打てる画面 で試すと、同じ結果になります。
SELECT juchu_on, COUNT(*) AS kensu, LAG(COUNT(*)) OVER (ORDER BY juchu_on) AS zenkai FROM juchu GROUP BY juchu_on ORDER BY juchu_on
| juchu_on | kensu | zenkai |
|---|---|---|
| 2025-11-05 | 1 | NULL |
| 2025-11-18 | 1 | 1 |
| 2025-12-02 | 1 | 1 |
| 2025-12-09 | 1 | 1 |
| 2025-12-24 | 1 | 1 |
| 2026-01-07 | 1 | 1 |
| 2026-01-21 | 1 | 1 |
| 2026-02-03 | 1 | 1 |
10 行(うち 8 行を表示)
いちばん上の行には前がないので NULL になります。
SELECT juchu_on, COUNT(*) AS kensu, COUNT(*) - LAG(COUNT(*), 1, 0) OVER (ORDER BY juchu_on) AS sa FROM juchu GROUP BY juchu_on ORDER BY juchu_on
| juchu_on | kensu | sa |
|---|---|---|
| 2025-11-05 | 1 | 1 |
| 2025-11-18 | 1 | 0 |
| 2025-12-02 | 1 | 0 |
| 2025-12-09 | 1 | 0 |
| 2025-12-24 | 1 | 0 |
| 2026-01-07 | 1 | 0 |
| 2026-01-21 | 1 | 0 |
| 2026-02-03 | 1 | 0 |
10 行(うち 8 行を表示)
説明
LAG は前の行、LEAD は後ろの行の値を、いまの行に並べて取り出します。「前の月からいくら増えたか」のような行どうしの比較を、自己結合なしで書けます。
引数は 3 つまで取れます。
- 第 1 引数 … 持ってきたい式
- 第 2 引数 … いくつ前か(既定 1)
- 第 3 引数 … 前の行が無いときに返す値(既定 NULL)
⚠️ 最初の行には前の行がありません。既定では NULL が入るので、そのまま引き算すると結果も NULL になります。0 を入れたいなら第 3 引数を書いてください。
PARTITION BY を付けると、区切りをまたいで持ってくることはありません。「顧客ごとの前回の受注日」のような使い方ができます。
ほかの製品でも通るか
未確認の製品があります そのまま使える: PostgreSQL / MySQL / MariaDB / SQLite / SQL Server
未確認: Oracle Database / IBM Db2
次に読む
根拠にした一次情報
- PostgreSQL 18 マニュアル: ウィンドウ関数(2026-09-02 確認)