情報処理試験を勉強していると、「副問合せと相関副問合せって何が違うの?」「EXISTSが出てきた瞬間に思考が止まる…」と混乱しがちです。
この記事では、副問合せ(サブクエリ)と相関副問合せの違いを、日常の例え話・SQL実行イメージ・HTML図解で整理します。
対象試験と出題頻度
副問合せ(サブクエリ)/ 相関副問合せは、基本情報技術者・応用情報技術者で出題されるテーマです。
SQLのデータ操作に関する問題として定番化しており、NOT INやEXISTSと組み合わせて「このSQL文の実行結果は何行か」を問う形式が繰り返し出題されています。
詳細をクリックして確認
基本情報技術者
応用情報技術者
★★★☆☆
ランクB(標準)覚えておくと有利
用語の定義
副問合せ(サブクエリ)とは、一言で言うと
「SQL文の内部にさらに埋め込まれたSELECT文」
のことです。
イメージとしては、「買い物リストの中にある”別の買い物リスト”」です。
「今日の夕飯の材料リスト」を作るとき、「カレーのレシピに書かれている材料一覧」を先に確認してから、それを夕飯リストに反映する場面を想像してください。
ここでの「カレーのレシピの材料一覧」が副問合せに当たります。メインの問合せが結果を出す前に、内側のSELECT文が先に実行されて値を返す仕組みです。
そして相関副問合せは、内側のSELECT文が外側の行を1行ずつ参照しながら繰り返し実行される特殊な副問合せです。「夕飯リストの品目ごとに、冷蔵庫の中身を毎回確認する」ような動きになります。
📊 副問合せ / 相関副問合せの基本情報
| 項目 | 副問合せ(通常) | 相関副問合せ |
|---|---|---|
| 英語名 | Subquery | Correlated Subquery |
| 実行回数 | 1回(結果を使い回す) | 外側の行数ぶん繰り返す |
| 外側への依存 | なし(独立して実行できる) | あり(外側の列を参照する) |
| よく組み合わせる句 | IN、NOT IN、比較演算子 | EXISTS、NOT EXISTS |
解説
データベースから情報を取り出すとき、単純な条件指定だけでは対応できない場面が頻繁に発生します。
たとえば「在庫が存在しない商品だけを抽出したい」「部署内に特定の職種の社員がいる部署を取り出したい」といった要件です。
こうした「別の問合せ結果を条件として使いたい」というニーズに応えるのが、SELECT文の入れ子構造です。
通常の副問合せの動作
通常の副問合せは、内側のSELECT文が先に1回だけ実行され、その結果セットを外側のWHERE句が条件として利用します。
内側と外側は独立しているため、内側だけを単体で実行しても正しい結果が返ります。
— 通常の副問合せ:在庫テーブルに存在しない商品番号を取得
SELECT 商品番号
FROM 商品
WHERE 商品番号 NOT IN (
SELECT 商品番号 FROM 在庫
);
このSQL文では、まず内側の SELECT 商品番号 FROM 在庫 が1回実行されて商品番号のリストが確定します。
次に外側が、そのリストに含まれない商品番号だけを商品テーブルから取り出します。
通常の副問合せの実行フロー
STEP 1
内側を1回実行
FROM 在庫
→ 結果:{101, 102, 104, 105}
渡す
STEP 2
外側がリストで抽出
FROM 商品
WHERE 商品番号 NOT IN (リスト)
→ 結果:{103, 106}
内側は1回だけ実行され、結果のリストを外側に渡す。内側と外側は独立している
相関副問合せの動作
相関副問合せは、内側のSELECT文が外側の現在処理中の行の値を参照します。
そのため外側の行を1行取り出すたびに内側が実行され、行数ぶんだけ繰り返されます。EXISTS / NOT EXISTSと組み合わせるのが典型的な書き方です。
— 相関副問合せ:在庫が30個を超える倉庫が存在しない製品番号を取得
SELECT 製品番号
FROM 製品 AS S1
WHERE NOT EXISTS (
SELECT * FROM 在庫 AS S2
WHERE S1.製品番号 = S2.製品番号
AND S2.在庫数 > 30
);
ポイントは S1.製品番号 = S2.製品番号 の部分です。内側が外側の S1.製品番号 を参照しているため、外側の製品テーブルの行が変わるたびに内側の検索条件も変わります。
相関副問合せの実行フロー
外側:製品テーブル
| 製品番号 | 判定 |
|---|---|
| AB1805 ◀ | 偽 |
| CC5001 | 偽 |
| MZ1000 | 真 |
| XZ3000 | 真 |
| ZZ9900 | 偽 |
1行ずつ上から処理
🔁 5行ぶんループ(行ごとに内側を実行)
② 内側を実行
WHERE S1.製品番号 = S2.製品番号
AND S2.在庫数 > 30
■青字が外側の値(行ごとに変わる)
内側:在庫テーブル
| 製品番号 | 在庫数 | >30? |
|---|---|---|
| AB1805 | 50 | ✓ |
| CC5001 | 40 | ✓ |
| CC5001 | 35 | ✓ |
| XZ3000 | 20 | ✗ |
| XZ3000 | 10 | ✗ |
| ZZ9900 | 45 | ✓ |
毎回ここを検索する
▲ AP R5秋 午前問29の題材をもとに作成。外側5行に対して内側が5回実行される
見分け方のポイント
両者を見分ける方法は単純です。
内側のSELECT文の中に、外側のテーブルの別名(エイリアス)が登場していれば相関副問合せ、登場していなければ通常の副問合せです。
先ほどのコード例でいえば、内側に S1.製品番号 という外側テーブルの列が書かれている時点で「相関」と判断できます。
| 比較観点 | 通常の副問合せ | 相関副問合せ |
|---|---|---|
| 内側を単独実行 | できる | できない(外側の値が必要) |
| 実行イメージ | 内側1回 → 外側1回 | 外側1行ごとに内側を繰り返す |
| 典型的な組み合わせ句 | IN / NOT IN | EXISTS / NOT EXISTS |
| 判別の決め手 | 内側に外側のエイリアスがない | 内側に外側のエイリアスがある |
では、これらが試験でどのように出題されるか見ていきましょう。
💡 核心を3行で
・副問合せ=SQL文の中に埋め込まれたSELECT文。内側が先に1回実行される
・相関副問合せ=外側の行を参照する副問合せ。外側の行数ぶん繰り返し実行される
・内側のSELECT文に外側テーブルのエイリアスがあれば「相関」と判断する
試験ではこう出る!
副問合せ・相関副問合せは、FE・APの午前問題でSQL文の実行結果を問う形式で繰り返し出題されています。出題パターンは大きく2つに分かれます。
📊 過去問での出題実績
| 試験回 | 出題内容 | 問われたポイント |
|---|---|---|
| AP R5秋 午前 問29 |
NOT EXISTSを使った相関副問合せの実行結果の行数を問う問題。 | ・主問合せの各行に対し内側が繰り返される仕組みを追えるか ・NOT EXISTSは「結果が0行のとき真」を返す |
| AP H28秋 午前 問29 |
NOT IN と EXISTS / NOT EXISTS の選択肢から正しいSQL文を選ぶ問題。 | ・NOT INと同じ結果を返すNOT EXISTS+相関副問合せの書き換えパターン ・EXISTSは「1行以上あれば真」 |
| FE H26春 午前 問28 |
NOT INの副問合せと同じ結果を返すSQL文を選ぶ問題。 | ・NOT INをNOT EXISTS+相関副問合せで書き換える定番パターン ・FE H22春 問31と同一構成(流用) |
| FE H20春 午前 問58 |
EXISTS+相関副問合せで、同じ部署にプログラマがいる部署コードを取得する問題。 | ・外側テーブルのエイリアスが内側に登場する構造を読み取れるか |
📝 IPA試験での出題パターン
パターン1:「このSQL文の結果は何行か」
テーブルのデータが示され、NOT EXISTSやINを使った副問合せの実行結果が何行になるかを計算させる形式。AP R5秋 問29が典型例。ここだけは確実に押さえてください。外側の行を1行ずつ追いかけて内側を実行し、真偽を判定する手順をトレースできれば正解に辿り着けます。
パターン2:「同じ結果を返すSQL文を選べ」
NOT INを使った副問合せが提示され、それと同じ結果になるNOT EXISTS+相関副問合せの構文を選ばせる形式。FE H26春 問28が代表例。ひっかけとして、EXISTSとNOT EXISTSの取り違えや、INとEXISTSの条件の向きの混同を狙う選択肢が配置されます。
試験ではここまででOKです。実行計画の最適化やパフォーマンスの違いまで問われることはないため、深追いは不要です。
【確認テスト】理解度チェック
ここまでの内容を理解できたか、簡単なクイズで確認してみましょう。
Q. 「相関副問合せ」の特徴として、最も適切なものはどれでしょうか?
- A. 内側のSELECT文が先に1回だけ実行され、その結果リストを外側のWHERE句がIN句で参照する。
- B. 複数のテーブルをJOIN句で結合し、結合結果に対してGROUP BYで集計を行う。
- C. 内側のSELECT文が外側の現在処理中の行の値を参照し、外側の行ごとに繰り返し実行される。
正解と解説を見る
正解:C
解説:
相関副問合せは、内側のSELECT文が外側(主問合せ)の処理中の行の列値を参照する構造のため、外側の行を1行取り出すたびに内側が実行されます。EXISTS / NOT EXISTSと組み合わせて「条件に合う行が存在するか」を判定するのが典型的な使い方です。
選択肢Aは通常の副問合せ(非相関副問合せ)の説明です。内側が独立して1回だけ実行される点が相関副問合せとは異なります。選択肢BはSELECT文の結合(JOIN)と集約(GROUP BY)の話であり、副問合せの分類とは無関係です。
よくある質問(FAQ)
Q. 副問合せはWHERE句以外にも書けますか?
書けます。SELECT句に副問合せを書いて「スカラサブクエリ」として1つの値を返す使い方や、FROM句に副問合せを書いて「インラインビュー(導出表)」として一時的な仮想テーブルを生成する使い方があります。ただし、IPA試験で出題されるのはWHERE句での使用がほとんどです。
Q. NOT INとNOT EXISTSは常に同じ結果になりますか?
NULLが含まれない場合は同じ結果になります。しかし、NOT INの比較対象にNULLが1つでも含まれると、SQLの3値論理(TRUE / FALSE / UNKNOWN)により結果が0行になる場合があります。NOT EXISTSはNULLの影響を受けないため、実務ではNOT EXISTSのほうが安全とされています。IPA試験の範囲では「NOT INとNOT EXISTS+相関副問合せは同等に書き換えられる」と理解していれば十分です。
Q. 相関副問合せは行数ぶん繰り返すので遅いのでは?
理論上は外側の行数ぶん内側が実行されるため非効率に見えます。しかし、現代のRDBMS(Oracle、PostgreSQL、MySQL 8.x以降など)はオプティマイザがクエリプランを最適化するため、実際にはJOINと同程度の速度で処理されるケースが多いです。試験対策としては「行数ぶん繰り返す」という論理的な動きを理解しておけば問題ありません。
Q. APの午後問題でも副問合せは出ますか?
出ます。APの午後「データベース」では、E-R図の読解とあわせてSQL文の穴埋めが出題されます。穴埋め箇所が副問合せの条件部分になるケースや、相関副問合せのWHERE句を完成させるケースが頻出です。午前で「NOT INとNOT EXISTSの書き換え」を押さえておけば、午後の穴埋めでも応用が利きます。