データ分析やレポート作成では、「順位付け」 や 「累計」 のような集計処理がよく登場します。
従来はサブクエリや自己結合を使う必要がありましたが、SQLの ウィンドウ関数(OVER句) を使えば簡潔に記述できます。
この記事では、代表的な使い方と主要DBMSごとの対応状況をサンプル付きで解説します。
🧠 ウィンドウ関数とは?
ウィンドウ関数とは、集計関数に対して「範囲(ウィンドウ)」を指定できる機能です。
通常の SUM() や AVG() はグループ全体を集計しますが、OVER() を使うことで「行単位の集計」も可能になります。
🔸 基本構文
| 句 | 役割 |
|---|---|
| PARTITION BY | グループを分ける(省略可) |
| ORDER BY | 並び順を指定 |
| ROWS BETWEEN ~ | 範囲を細かく指定(任意) |
🏅 ランキングを求める
商品の売上データを例に、売上額で順位をつけます。
📘 サンプルテーブル:sales
| product | category | amount |
|---|---|---|
| A | 飲料 | 300 |
| B | 飲料 | 500 |
| C | 食品 | 400 |
| D | 食品 | 200 |
| E | 食品 | 700 |
📗 SQL例
📊 実行結果
| category | product | amount | rank |
|---|---|---|---|
| 飲料 | B | 500 | 1 |
| 飲料 | A | 300 | 2 |
| 食品 | E | 700 | 1 |
| 食品 | C | 400 | 2 |
| 食品 | D | 200 | 3 |
✅ ポイント
-
同じカテゴリ内で順位を付与 (
PARTITION BY category) -
売上が高い順に並び替え (
ORDER BY amount DESC) -
RANK()は同順位がある場合にスキップ(例:1位,1位,3位)
🔢 累計を求める
カテゴリ別に売上の累計を出してみましょう。
📗 SQL例
📊 結果
| category | product | amount | running_total |
|---|---|---|---|
| 飲料 | B | 500 | 500 |
| 飲料 | A | 300 | 800 |
| 食品 | E | 700 | 700 |
| 食品 | C | 400 | 1100 |
| 食品 | D | 200 | 1300 |
✅ ポイント
-
SUM()にOVER()を組み合わせることで行ごとの累積が可能 -
ORDER BYにより順序を指定できる -
PARTITION BYを省略すると全体累計に
🧮 他の代表的なウィンドウ関数
| 関数 | 説明 |
|---|---|
| ROW_NUMBER() | 連番(重複なし)を付与 |
| RANK() | 同順位があるとスキップ(例:1,1,3) |
| DENSE_RANK() | 同順位があっても連続(例:1,1,2) |
| NTILE(n) | n等分にグループ分け(例:四分位) |
| LAG(col, n) | n行前の値を取得 |
| LEAD(col, n) | n行後の値を取得 |
| SUM(), AVG(), MAX(), MIN() | 累計・平均などの集計を行単位で |
💡 応用例:前回比を計算する
前回の売上からの増減を求めたい場合は LAG() 関数を使用します。
🧭 DBMS別のウィンドウ関数対応表
| DBMS | 対応状況 | 対応バージョン | 備考 |
|---|---|---|---|
| Oracle Database | ◎ 完全対応 | 8i 以降 | ウィンドウ関数発祥の実装。機能最も豊富 |
| PostgreSQL | ◎ 完全対応 | 8.4 以降 | PARTITION, ORDER, RANGE句など全対応 |
| MySQL | ○ 部分対応 | 8.0 以降 | 8.0から正式対応(それ以前は非対応) |
| SQL Server | ◎ 完全対応 | 2012 以降 | LAG/LEADなどもサポート |
| SQLite | ○ 部分対応 | 3.25 以降 | 一部関数は制限あり(NTILEなど) |
| MariaDB | △ 限定対応 | 10.2 以降 | SUMなどは対応、LAG/LEADは制限あり |
| IBM Db2 | ◎ 完全対応 | 9.7 以降 | 分析関数として強力なサポートあり |
| Snowflake / BigQuery | ◎ 完全対応 | 最新 | クラウドDWH系でもネイティブ対応 |
✅ 補足
-
旧バージョンのMySQL(5.x系)ではウィンドウ関数が非対応のため、サブクエリで代替が必要。
-
PostgreSQLとOracleは
ROWS BETWEENなどの範囲指定も細かく制御可能。 -
BigQueryは
OVER()句のほかQUALIFY句でフィルタリングが可能。
🔍 まとめ
| 観点 | 内容 |
|---|---|
| 機能 | グループ単位での行ごとの集計・順位付け |
| 主な用途 | 累計・ランキング・前回比・順位比較 |
| メリット | サブクエリ不要・可読性向上・パフォーマンス改善 |
| 対応DB | Oracle, PostgreSQL, SQL Server, MySQL 8+, BigQueryなど |
ウィンドウ関数は、分析SQLの最重要機能といっても過言ではありません。
集計・比較・順位などを自在に扱えるようになれば、レポート作成の幅が大きく広がります。
