データベーススペシャリスト試験や応用情報技術者試験の午後問題で頻出の「ウィンドウ関数」。SQLの上級者向け機能でありながら、「そもそも何が“ウィンドウ”なの?」「GROUP BYとの違いがいまいち分からない」と感じる方も多いのではないでしょうか。
実務では売上ランキングの計算や累積値の集計、人事評価の並び替えなど、データの“部分的な集計”が必要な場面でウィンドウ関数は非常に強力なツールになります。しかし、その「直感的に分かりにくい概念性」が、学習のハードルを上げているのも事実です。
この記事では、ウィンドウ関数とは何か、なぜ“ウィンドウ”という名前がついているのかといった語源・概念の理解から始め、試験で狙われやすい出題パターンやよくある引っかけポイントまでを、図解・具体例・比喩を交えて体系的に解説します。
PARTITION BY と GROUP BY の混同を解きほぐしながら、「なぜそれが必要なのか」まで腹落ちさせることを目指します。
目次
ウィンドウ関数の語源と基本概念│なぜ“ウィンドウ”なのかを図解で理解する
SQLにおける「ウィンドウ関数」とは、行ごとの計算において“集計の枠(ウィンドウ)”を指定して処理を行う関数のことです。
例えば「各部署ごとの給与順位」や「各月ごとの累積売上」など、全体ではなく“ある範囲内”での集計を行いたいときに使われます。
🔍 なぜ「ウィンドウ」なのか?
“ウィンドウ(window)”とは、日本語で言う「窓」ではなく、「範囲」「枠組み」の意味です。
つまり、ウィンドウ関数は「ある範囲(枠)を定義し、その中で集計・順位付けなどを行う」機能なのです。
📊 図解:通常の集計 vs ウィンドウ関数
ID | 部署 | 給与 | 部署内順位(ウィンドウ関数) |
---|---|---|---|
1 | 営業 | 300 | 2 |
2 | 営業 | 500 | 1 |
3 | 総務 | 280 | 2 |
4 | 総務 | 340 | 1 |
→ これは RANK() OVER (PARTITION BY 部署 ORDER BY 給与 DESC)
によって、部署ごとに給与を並び替えた例です。
GROUP BY では「営業」「総務」それぞれ1行にしかならず、このような行単位の情報保持と集計の併用はできません。
💡 ここで追加質問:
「GROUP BY でも集計できるなら、なぜわざわざウィンドウ関数を使うの?」
次セクションではこの疑問を解決します!
GROUP BYとの違いとPARTITION BYの意味│ウィンドウ関数の“部分集計”を直感的に理解する
SQL初学者がウィンドウ関数で最も混乱しやすいのが、「GROUP BYとどう違うの?」という点です。
結論から言えば、GROUP BYは“行をまとめる”集計、PARTITION BYは“まとめずに、範囲を指定して集計”する機能です。
🧠 比喩で理解:「GROUP BYは集団写真、PARTITION BYは名簿の横にメモ」
- GROUP BY:各部署の代表を1人ずつ並べて、集合写真を撮る →「1部署=1行」のデータになる
- PARTITION BY:全社員が名簿に並んだまま、横に「この人は部署内で何位」などメモを書き加える → 行数はそのまま!
🔍 実例比較:GROUP BY vs ウィンドウ関数
テーブル例(社員データ)
ID | 部署 | 給与 |
---|---|---|
1 | 営業 | 300 |
2 | 営業 | 500 |
3 | 総務 | 280 |
4 | 総務 | 340 |
📌 GROUP BY を使った場合
SELECT 部署, AVG(給与) FROM 社員 GROUP BY 部署;
部署 | 平均給与 |
---|---|
営業 | 400 |
総務 | 310 |
→ 「部署ごとに集計」して、行数が部署数に減る
📌 ウィンドウ関数(PARTITION BY)を使った場合
SELECT *, AVG(給与) OVER (PARTITION BY 部署) AS 部署別平均
FROM 社員;
ID | 部署 | 給与 | 部署別平均 |
---|---|---|---|
1 | 営業 | 300 | 400 |
2 | 営業 | 500 | 400 |
3 | 総務 | 280 | 310 |
4 | 総務 | 340 | 310 |
→ 行数は変わらず、集計結果を“追加情報として横に貼る”のがウィンドウ関数の特徴です。
✔ POINT:GROUP BYとPARTITION BYの違いまとめ表
比較軸 | GROUP BY | PARTITION BY(ウィンドウ関数) |
---|---|---|
行数 | 減る(グループ単位になる) | 変わらない(全行を保持) |
表示できる列 | GROUP列か集計列のみ | すべての列をそのまま表示可能 |
用途 | グループごとの集計 | 行単位の集計+元の情報の同時表示 |
ウィンドウ関数の使いどころとNG例│試験や実務で使われるパターンと避けるべきケース
ウィンドウ関数は非常に柔軟な機能ですが、「何でもウィンドウ関数で済ませればいい」というわけではありません。
このセクションでは、よく使われる代表的な場面と、逆に使わない方が適切なケースをセットで紹介します。
✅ よく使われるシーン(試験にも頻出)
シーン | 内容 | 具体例 |
---|---|---|
ランキング付け | 同順位の扱いや行ごとの順位表示が必要 | RANK() / ROW_NUMBER() |
累積集計 | 日別・月別に積み上げていくデータ処理 | SUM() OVER (ORDER BY 日付) |
部分平均 | カテゴリごとに平均・最大・最小を出す | AVG() OVER (PARTITION BY カテゴリ) |
前後比較 | 前月比・前年差分など | LAG() / LEAD() |
🔍 試験に出やすい組み合わせパターン
- PARTITION BY + ORDER BY:集計対象と並び順を明示
- RANK vs ROW_NUMBER:同値の扱いで結果が異なる
- LAG/LEAD の OFFSET:前行・後行が存在しないときの NULL 処理が問われる
⚠ ウィンドウ関数を避けた方がいいケース
ケース | 理由 | 代替案 |
---|---|---|
データ件数が膨大 | ウィンドウ関数は重い。パフォーマンス悪化 | サマリテーブル or 一時テーブル |
シンプルな合計だけでよい | GROUP BY の方が読みやすく軽い | 通常の GROUP BY |
データ結合(JOIN)を優先すべきとき | ウィンドウ関数より JOIN の方が意味が明確 | サブクエリ + JOIN |
💡 POINT:試験では“使うべきか見極める力”が問われる
午後試験では、必ずしも「ウィンドウ関数を使え」という意図ではなく、「最適な手段を選べるか?」がポイントです。
そのため、「すべてをウィンドウ関数で解決しよう」とするのではなく、「これはGROUP BYの方が適切では?」という視点も重要です。
午後試験で狙われるSQLキーワードとウィンドウ関数の連携パターン
IPAのデータベース系試験では、「ウィンドウ関数そのもの」よりも、「ウィンドウ関数+他のSQL構文」の組み合わせパターンで問われるケースが多く見られます。
ここでは試験に頻出するキーワードと、ウィンドウ関数との“連動関係”を具体的に紹介します。
✅ 試験でよく出るSQLキーワードと使い方
キーワード | 連動ポイント | ウィンドウ関数との関連例 |
---|---|---|
OVER |
ウィンドウ関数の本体部分 | SUM() OVER (...) など |
PARTITION BY |
グループ分け | カテゴリや部署単位の計算 |
ORDER BY (OVER句内) |
並び順指定 | 累積、ランキング系の正確な計算に必要 |
RANK() / ROW_NUMBER() |
順位の算出 | 並び替え・重複の扱いに違いあり |
LAG() / LEAD() |
前後の値の参照 | 前回との差分、遷移検出など |
CASE |
条件による振り分け | ウィンドウ関数の結果をもとに条件分岐 |
🔍 具体的な連携パターン例
① 累積売上をカテゴリ別に計算
SELECT 商品カテゴリ, 売上日, 売上金額,
SUM(売上金額) OVER (PARTITION BY 商品カテゴリ ORDER BY 売上日) AS 累積売上
FROM 売上データ;
→ カテゴリごとに日付順で売上を積み上げる処理。ORDER BY の重要性が問われやすい
② 前回との差分を出す(LAGとの組み合わせ)
SELECT 社員ID, 月, 勤怠時間,
勤怠時間 - LAG(勤怠時間) OVER (PARTITION BY 社員ID ORDER BY 月) AS 増減
FROM 勤怠記録;
→ LAG関数と演算を組み合わせるパターンは頻出。NULL考慮の選択肢もよく出題される。
③ ランキングで上位3位までを抽出(RANK + サブクエリ)
SELECT * FROM (
SELECT 社員ID, 部署, 給与,
RANK() OVER (PARTITION BY 部署 ORDER BY 給与 DESC) AS 順位
FROM 社員
) AS ランク付け
WHERE 順位 <= 3;
→ 部署ごとに給与順位を付けて「上位3人のみ」を抽出。RANK関数+サブクエリがよく使われる。
④ 最新月の値と過去月の差を比較(LEAD+日付条件)
SELECT 商品ID, 月, 売上,
売上 - LEAD(売上) OVER (PARTITION BY 商品ID ORDER BY 月 DESC) AS 前月比
FROM 売上データ;
→ LEAD関数と演算を組み合わせたパターン。ORDER BY の DESC 指定に注意。
⑤ 条件に応じて集計対象を切り替える(CASE+ウィンドウ関数)
SELECT 社員ID, 勤務区分, 勤務時間,
SUM(CASE WHEN 勤務区分 = '通常' THEN 勤務時間 ELSE 0 END)
OVER (PARTITION BY 社員ID ORDER BY 日付) AS 通常勤務累積
FROM 勤怠記録;
→ CASEで条件分岐した累積集計。試験では「条件に応じた集計」が頻出です。
💡 試験対策のコツ
- OVER句の中身を読めば、何が起きているか分かるようになる
- ORDER BYがないと、期待通りに並ばない=減点されやすい
- RANK系とROW_NUMBERの違いに着目せよ
試験でのひっかけポイントと間違えやすい落とし穴│ウィンドウ関数の誤用に注意
午後試験では、ウィンドウ関数の「基本的な書き方」よりも、“微妙な違いによる誤答”を誘う選択肢が多く出題されます。
ここでは、受験生がつまずきやすいポイントや、よくあるミスを整理します。
❗ よくある間違いとその原因
ミス例 | 原因 | 正しい理解 |
---|---|---|
OVER に ORDER BY を書き忘れる |
デフォルトの並びで集計され、順位や累積結果が想定外になる | 並び順は常に意識して指定する |
PARTITION BY を使い忘れる |
全体で集計されてしまい、「部署ごとの平均」などが破綻 | 必要な単位ごとに区切る |
RANK() と ROW_NUMBER() の使い分けミス |
同順位あり/なしで結果が大きく変わる | 問題の意図を確認して選択する |
LAG() の NULL を考慮しない |
初回の行で差分計算が崩れる | COALESCE() などで補う処理が必要な場合あり |
📌 試験でよく出る“ひっかけポイント”
- PARTITION BY の指定があるか・ないかの違いを読み落とさせる
- ORDER BY の順序(ASC / DESC)で意味が逆転する選択肢
- RANK系の数値のズレに着目できるか
- NULLに対する理解(初行のLAG/LEADの扱い)を問う設問
✅ 回避のためのチェックリスト
- OVER句の中に
PARTITION BY
とORDER BY
が適切にあるか? - 集計対象の粒度は正しいか(部署単位、日付単位など)?
- 順位の扱い(同順位あり/なし)は設問に合っているか?
- NULLが返る可能性のある関数に対して補正が必要か?
まとめ│ウィンドウ関数を“理解して使える”技術にするために
ウィンドウ関数は「ただのSQL関数の一種」と捉えると難解ですが、「部分集計のための“窓”を開く道具」と考えることで、実務でも試験でも強力な武器になります。
この記事で紹介したように、GROUP BY との違いや PARTITION BY・ORDER BY の正しい使い方、LAG/LEAD などとの組み合わせパターンを押さえることが、午後試験対策の要になります。
- ウィンドウ関数は「集計+詳細の同時表示」が得意
- GROUP BY では実現できない“行ごとの相対処理”を補える
- 試験では「微妙な指定漏れ」による誤答を誘う問題に注意
単なる丸暗記ではなく、概念を直感的に理解し、適切な場面で使いこなす力を身につけることが、スコアアップへの近道です。