## What — 集約せずに集計する関数
`GROUP BY` の集約は、複数の行を1行に潰してしまう。ウィンドウ関数は元の行数を保ったまま、各行に対して「その行が属するグループでの集計値」や「並び順の中での位置」を付け足す。ユーザーごとの累計、日付順の前日比、カテゴリ内の順位といった「行を残したまま比べる」処理はこれで書ける。
## How — 基本構文と3つのパーツ
``` SQL
ウィンドウ関数名 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` 句で外側から条件を掛ける。
## 関連
- [[Google Cloud]]
- [[データ基盤]]
- [[BigQuery]]
- [[Cloud StorageとBigQuery]]