SQLで集計や分析をしていると、
-
「1つ前の行の値と比較したい」
-
「次の行の値を参照したい」
-
「前回との差分を出したい」
といったケースは非常によくあります。
このようなときに使うのが、ウィンドウ関数(分析関数)のLAG と LEAD です。
この記事では、
-
前の行の値を取得する方法
-
後の行の値を取得する方法
-
よくある使用例
-
DBごとの対応状況
を分かりやすく解説します。
基本構文
|
1 2 3 |
LAG(対象カラム [, ずらす行数 [, デフォルト値]]) OVER (ORDER BY 並び順)<code class="whitespace-pre! language-sql"> |
使用例
|
1 2 3 4 5 6 |
SELECT id, sales, LAG(sales) OVER (ORDER BY id) AS prev_sales FROM sales_table;<code class="whitespace-pre! language-sql"> |
実行イメージ
| id | sales | prev_sales |
|---|---|---|
| 1 | 100 | NULL |
| 2 | 120 | 100 |
| 3 | 150 | 120 |
👉 1つ前の行の値が取得できます。
後の行の値を取得する:LEAD関数
基本構文
|
1 2 3 |
LEAD(対象カラム [, ずらす行数 [, デフォルト値]]) OVER (ORDER BY 並び順)<code class="whitespace-pre! language-sql"> |
使用例
|
1 2 3 4 5 6 |
SELECT id, sales, LEAD(sales) OVER (ORDER BY id) AS next_sales FROM sales_table;<code class="whitespace-pre! language-sql"> |
実行イメージ
| id | sales | next_sales |
|---|---|---|
| 1 | 100 | 120 |
| 2 | 120 | 150 |
| 3 | 150 | NULL |
👉 1つ後の行の値が取得できます。
差分を計算する(前回との差)
|
1 2 3 4 5 6 |
SELECT id, sales, sales - LAG(sales) OVER (ORDER BY id) AS diff_sales FROM sales_table;<code class="whitespace-pre! language-sql"> |
結果例
| id | sales | diff_sales |
|---|---|---|
| 1 | 100 | NULL |
| 2 | 120 | 20 |
| 3 | 150 | 30 |
📌 売上増減・ログの変化量・履歴比較で非常によく使われます。
デフォルト値を指定する
先頭行・最終行では NULL になるのが困る場合、
第3引数でデフォルト値を指定できます。
|
1 2 |
LAG(sales, 1, 0) OVER (ORDER BY id)<code class="whitespace-pre! language-sql"> |
👉 前の行が存在しない場合は 0 が入ります。
PARTITION BY でグループごとに比較する
|
1 2 3 4 5 6 7 8 9 10 |
SELECT category, id, sales, LAG(sales) OVER ( PARTITION BY category ORDER BY id ) AS prev_sales FROM sales_table;<code class="whitespace-pre! language-sql"> |
📌 カテゴリ別・ユーザー別・日付別など
グループ単位で前後行を比較できます。
対応している主なDB
| DB | LAG / LEAD |
|---|---|
| Oracle | ○ |
| PostgreSQL | ○ |
| SQL Server | ○ |
| MySQL | ○(8.0以降) |
| MariaDB | ○(10.2以降) |
※ MySQL 5.x では使用できないため注意してください。
まとめ
-
前の行を取得 → LAG
-
後の行を取得 → LEAD
-
差分計算・履歴比較・ランキング分析に必須
-
OVER (ORDER BY ...)を忘れない -
必要に応じて
PARTITION BYを使う
SQLで「前後の行を参照したい」と思ったら、
まず LAG / LEAD を思い出すのが王道です。

