LAG関数とは
LAG 関数は一言でいうと、
「前の行の値を参照するための関数」です。
SQL は基本的に「行同士の関係」を意識せずに処理しますが、
LAG 関数を使うことで、
・前日との差分
・前回の売上との比較
・前のステータスとの変化
といった “時系列の文脈” をSQLに持たせることができます。
LAG 関数の基本構文
SnowflakeにおけるLAG関数の基本構文
LAG(対象カラム, 何行前か, デフォルト値)
OVER (
PARTITION BY 分割条件
ORDER BY 並び順
)
・LAG = 過去を見る
・OVER句で「どの順番で」「どの単位で」過去に戻るかを決める
よくある利用シーン
LAG関数は以下のような場面でよく活用されます。
・前日比・前月比の算出
・ステータス変更の検知
・累積値の増減チェック
・異常値(急増・急減)の発見
サンプルデータでLAG関数を理解する
以下のようなサンプルデータを用意します。
テーブル名:SALES_DAILY

Case1:LAG関数を使って「前日の売上」を取得する
SELECT
STORE_ID,
SALES_DATE,
SALES_AMOUNT,
LAG(SALES_AMOUNT, 1) OVER (
PARTITION BY STORE_ID
ORDER BY SALES_DATE
) AS PREV_SALES_AMOUNT
FROM SALES_DAILY
ORDER BY STORE_ID, SALES_DATE;
クエリの実行結果は以下のようになります。

POINT
・PARTITION BY STORE_ID
→ 店舗ごとに「前日」を計算
・ORDER BY SALES_DATE
→ 日付順に「前」を定義
・最初の日は前日が存在しないため NULL
Case2:LAG関数を使って「前日比(差分)」を計算してみる
SELECT
STORE_ID,
SALES_DATE,
SALES_AMOUNT,
SALES_AMOUNT
- LAG(SALES_AMOUNT) OVER (
PARTITION BY STORE_ID
ORDER BY SALES_DATE
) AS DIFF_FROM_PREV_DAY
FROM SALES_DAILY
ORDER BY STORE_ID, SALES_DATE;
クエリの結果は以下のようになります。

増減が一目でわかるようになりました。
PARTITION BY と ORDER BY の役割
・ORDER BY
どの順番で「前」を定義するか
時系列分析ではほぼ必須
・PARTITION BY
どのグループごとに LAG を計算するか
店舗別、ユーザー別、商品別などに使う
例:店舗ごとの前日売上
LAG(sales_amount)
OVER (
PARTITION BY store_id
ORDER BY sales_date
)
NULL を回避したい場合
最初の行を 0 扱いにしたい場合は、第3引数を使います。
LAG(SALES_AMOUNT, 1, 0)
以下のようにクエリを修正し、実行すると初日が null にならず 0 で出力されます。
SELECT
STORE_ID,
SALES_DATE,
SALES_AMOUNT,
LAG(SALES_AMOUNT, 1, 0) OVER (
PARTITION BY STORE_ID
ORDER BY SALES_DATE
) AS PREV_SALES_AMOUNT
FROM SALES_DAILY
ORDER BY STORE_ID, SALES_DATE;

LAG関数を使用する際の注意点
・LAG関数はウィンドウ関数のため、WHERE句は使えない
・結果にフィルタをかけたい場合はサブクエリを使う
・ORDER BYを忘れると、意図しない結果になりがち
まとめ
LAG関数を使うことで、
・SQLがシンプルになる
・可読性が上がる
・分析の表現力が一気に広がる
ということで、実務でもしっかり活用できるようにしていきたいと思います。
