IPA情報処理試験キーワード

IPA|情報処理技術者試験

ウィンドウ関数とは?SQL試験で差がつくGROUP BYとの違いと出題対策

データベーススペシャリスト試験や応用情報技術者試験の午後問題で頻出の「ウィンドウ関数」。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の違いに着目せよ

試験でのひっかけポイントと間違えやすい落とし穴│ウィンドウ関数の誤用に注意

午後試験では、ウィンドウ関数の「基本的な書き方」よりも、“微妙な違いによる誤答”を誘う選択肢が多く出題されます。
ここでは、受験生がつまずきやすいポイントや、よくあるミスを整理します。

❗ よくある間違いとその原因

ミス例 原因 正しい理解
OVERORDER BY を書き忘れる デフォルトの並びで集計され、順位や累積結果が想定外になる 並び順は常に意識して指定する
PARTITION BY を使い忘れる 全体で集計されてしまい、「部署ごとの平均」などが破綻 必要な単位ごとに区切る
RANK()ROW_NUMBER() の使い分けミス 同順位あり/なしで結果が大きく変わる 問題の意図を確認して選択する
LAG() の NULL を考慮しない 初回の行で差分計算が崩れる COALESCE() などで補う処理が必要な場合あり

📌 試験でよく出る“ひっかけポイント”

  • PARTITION BY の指定があるか・ないかの違いを読み落とさせる
  • ORDER BY の順序(ASC / DESC)で意味が逆転する選択肢
  • RANK系の数値のズレに着目できるか
  • NULLに対する理解(初行のLAG/LEADの扱い)を問う設問

✅ 回避のためのチェックリスト

  • OVER句の中に PARTITION BYORDER BY が適切にあるか?
  • 集計対象の粒度は正しいか(部署単位、日付単位など)?
  • 順位の扱い(同順位あり/なし)は設問に合っているか?
  • NULLが返る可能性のある関数に対して補正が必要か?

コラム:集計関数とGROUP BY、そしてウィンドウ関数の真価

SQLを学んでいて混乱しやすいのが「集計関数とGROUP BYの関係」と「ウィンドウ関数におけるPARTITION BY・ORDER BYの役割」です。最後に整理しておきましょう。

前提:元データ

以下の売上テーブルを例に説明します。

日付 部署 名前 売上
2025-09-01 営業 田中 100
2025-09-02 営業 鈴木 150
2025-09-03 開発 佐藤 200
2025-09-04 開発 山田 50

集計関数とGROUP BYの関係

SELECT 部署, SUM(売上)
FROM 売上テーブル
GROUP BY 部署;

結果

部署 SUM(売上)
営業 250
開発 250

ウィンドウ関数と PARTITION BY / ORDER BY

SELECT
  部署,
  名前,
  売上,
  SUM(売上) OVER (PARTITION BY 部署) AS 部署合計,
  SUM(売上) OVER (PARTITION BY 部署 ORDER BY 日付) AS 部署累計
FROM 売上テーブル;

結果

部署 名前 売上 部署合計 部署累計
営業 田中 100 250 100
営業 鈴木 150 250 250
開発 佐藤 200 250 200
開発 山田 50 250 250

OVER() のかっこ内が空のとき

SELECT
  日付,
  名前,
  売上,
  SUM(売上) OVER () AS 総売上
FROM 売上テーブル;

結果

日付 名前 売上 総売上
2025-09-01 田中 100 500
2025-09-02 鈴木 150 500
2025-09-03 佐藤 200 500
2025-09-04 山田 50 500

LAG / LEAD での前後比較

SELECT
  日付,
  名前,
  売上,
  LAG(売上, 1)  OVER (ORDER BY 日付) AS 前日売上,
  LEAD(売上, 1) OVER (ORDER BY 日付) AS 翌日売上
FROM 売上テーブル;

結果

日付 名前 売上 前日売上 翌日売上
2025-09-01 田中 100 NULL 150
2025-09-02 鈴木 150 100 200
2025-09-03 佐藤 200 150 50
2025-09-04 山田 50 200 NULL

RANK による順位付け

SELECT
  名前,
  売上,
  RANK() OVER (ORDER BY 売上 DESC) AS 売上順位
FROM 売上テーブル;

結果

名前 売上 売上順位
佐藤 200 1
鈴木 150 2
田中 100 3
山田 50 4

【重要】RANK の ORDER BY は OVER() の内側に必要

外側(SELECT の最後)の ORDER BY はあくまで「表示順」を決めるだけで、順位の計算には影響しません。
順位の基準は必ず OVER(ORDER BY ...)内側で指定します。

ROW_NUMBER による連番付与

SELECT
  名前,
  売上,
  ROW_NUMBER() OVER (ORDER BY 売上 DESC) AS 行番号
FROM 売上テーブル;

結果

名前 売上 行番号
佐藤 200 1
鈴木 150 2
田中 100 3
山田 50 4

【注意】ROW_NUMBER の順序保証

ROW_NUMBER() はユニークな連番を振りますが、どの順番で番号が付くかOVER(ORDER BY ...) の内側に書かないと保証されません。
もし OVER() を空にして外側にだけ ORDER BY を書いた場合、表示順は並び替えられても、番号の付与順序は内部処理依存となり、環境や実行計画によって変わる危険があります。

👉 したがって、必ず OVER 内の ORDER BY で順序を指定するのが正しい書き方です。

コラムまとめ

  • 集計関数+GROUP BY:行をまとめて短くする(グループの数だけ出力)
  • ウィンドウ関数+OVER():行を残したまま「全体の集計結果」を列として追加
  • ウィンドウ関数+PARTITION BY:行を残したまま「グループ単位の情報」を列として追加
  • ウィンドウ関数+ORDER BY:順序依存の計算(累計、LAG/LEAD、順位付け、連番付け)を可能にする
  • RANK / ROW_NUMBER の ORDER BY は OVER 内に必須(外側の ORDER BY は表示順だけを制御)

ウィンドウ関数を使えば、「集計」「比較」「順位付け」「連番付け」を、元の行を保持したまま自在に組み合わせられます。

まとめ│ウィンドウ関数を“理解して使える”技術にするために

ウィンドウ関数は「ただのSQL関数の一種」と捉えると難解ですが、「部分集計のための“窓”を開く道具」と考えることで、実務でも試験でも強力な武器になります。

この記事で紹介したように、GROUP BY との違いや PARTITION BY・ORDER BY の正しい使い方、LAG/LEAD などとの組み合わせパターンを押さえることが、午後試験対策の要になります。

  • ウィンドウ関数は「集計+詳細の同時表示」が得意
  • GROUP BY では実現できない“行ごとの相対処理”を補える
  • 試験では「微妙な指定漏れ」による誤答を誘う問題に注意

単なる丸暗記ではなく、概念を直感的に理解し、適切な場面で使いこなす力を身につけることが、スコアアップへの近道です。

-IPA|情報処理技術者試験
-