imu-note
いむたろ
いむたろ
@imutaroh
新卒エンジニア / データ基盤 × AI

What — 集約せずに集計する関数

GROUP BY の集約は、複数の行を1行に潰してしまう。ウィンドウ関数は元の行数を保ったまま、各行に対して「その行が属するグループでの集計値」や「並び順の中での位置」を付け足す。ユーザーごとの累計、日付順の前日比、カテゴリ内の順位といった「行を残したまま比べる」処理はこれで書ける。

How — 基本構文と3つのパーツ

ウィンドウ関数名 OVER (
PARTITION BY フィールド名
ORDER BY フィールド名
WINDOWフレーム
)

OVER () の中身が、その行から見える範囲(ウィンドウ)の定義になる。

  • PARTITION BY … 集計を区切る単位。GROUP BY に相当するが、行は潰れない。省略するとテーブル全体が1つの区切りになる
  • ORDER BY … 区切りの中での並び順。順位や累計、前後の行の参照はこの順序が基準になる
  • ウィンドウフレーム … 並び順のどこからどこまでを計算に入れるか(ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW なら先頭から現在行まで=累計)。省略時は ORDER BY の有無でデフォルトが変わる

よく使う関数はこのあたり。

  • ROW_NUMBER() / RANK() / DENSE_RANK() … 区切りの中での順位。「ユーザーごとの最新1件」を取るときは ROW_NUMBER() で採番して1番だけ残す
  • SUM() / AVG() / COUNT() … 通常の集約関数も OVER () を付ければウィンドウ関数として使える(累計・移動平均)
  • LAG() / LEAD() … 前の行・次の行の値を持ってくる。前日比や離脱の判定に使う
Warning

ウィンドウ関数は WHERE では絞り込めない(評価される順番が WHERE より後)。順位で絞りたいときは、サブクエリや QUALIFY 句で外側から条件を掛ける。

関連