最終更新日:2026年9月27日
fe fe-technology database sql
まず結論
相関サブクエリとは、サブクエリの中から外側の問合せの行を参照して判定するSQLです。
基本情報技術者試験では、次の3点を押さえると選択肢を切りやすくなります。
内側で外側の別名を参照している
→ 相関サブクエリ
COUNTで件数を求める
→ 該当行が0件でも0として比較できる
EXISTS / IN
→ 該当する行・値が存在しなければ候補にならない
特に重要なのは、
「5件未満」には0件も含まれる
という点です。
0件を条件に含めたい問題では、「0を返せるSQLなのか」「そもそも候補行が消えてしまわないか」まで確認します。
直感的な説明
例えば、部署ごとの「プログラマ人数が3人未満」の部署を探すとします。
相関サブクエリでは、外側の部署を1つずつ見ながら、その部署に属するプログラマの人数を内側で数えるイメージです。
外側:部署Aを見る
↓
内側:部署Aのプログラマを数える
↓
2人 → 3人未満なので残す
外側:部署Bを見る
↓
内側:部署Bのプログラマを数える
↓
0人 → 3人未満なので残す
外側:部署Cを見る
↓
内側:部署Cのプログラマを数える
↓
4人 → 3人未満ではないので除外
ポイントは、内側の問合せを独立して読むのではなく、外側の現在行を渡して実行することです。
定義・仕組み
相関サブクエリ
次のSQLを考えます。
SELECT DISTINCT A.部署コード
FROM 社員 A
WHERE 3 > (
SELECT COUNT(*)
FROM 社員 B
WHERE B.部署コード = A.部署コード
AND B.職務 = 'プログラマ'
);
内側のSQLには、外側の表別名 A が登場しています。
B.部署コード = A.部署コード
この条件によって、
「今、外側で見ている社員と同じ部署」
という意味になります。
したがって、外側の各行について内側の件数を求め、条件を満たすか判定します。
COUNTは0件でも0を返す
COUNT(*) は、条件に合う行の件数を返します。
3件見つかる
→ COUNT(*) = 3
1件見つかる
→ COUNT(*) = 1
1件も見つからない
→ COUNT(*) = 0
そのため、
3 > (SELECT COUNT(*) ...)
なら、0件も条件を満たします。
0 < 3 → TRUE
1 < 3 → TRUE
2 < 3 → TRUE
3 < 3 → FALSE
COUNT(列名) はNULLを除いて数えるため、単純な行数を数えたいときは COUNT(*) が分かりやすいです。列にNULLがないことが分かっている場合は、COUNT(列名) でも同じ件数になります。
集計関数そのものの基本は、SQLの集計関数とは?COUNT・SUM・AVG・MAXとWHEREの違いで整理しています。
GROUP BYでは「0件のグループ」は作られない
次のように、先にプログラマだけへ絞ってから部署ごとにまとめる場合を考えます。
SELECT 部署コード
FROM 社員
WHERE 職務 = 'プログラマ'
GROUP BY 部署コード
HAVING COUNT(*) < 3;
プログラマが1人または2人いる部署は抽出できます。
しかし、プログラマが0人の部署は、
WHERE 職務='プログラマ'
↓
残る行が0件
↓
GROUP BYする行がない
↓
部署のグループ自体が作られない
ため、結果に現れません。
ここが試験で非常に重要な違いです。
COUNTが0を返すことと、GROUP BYの結果に0件のグループが現れることは別です。
GROUP BY と HAVING の基本は、SQLのGROUP BYとは?集計関数・WHERE・HAVINGの見分け方で確認できます。
EXISTSは「1件でもあるか」を見る
EXISTS は、サブクエリが1行でも返せばTRUEになります。
WHERE EXISTS (
SELECT 1
FROM 社員 B
WHERE B.部署コード = A.部署コード
AND B.職務 = 'プログラマ'
)
これは、
同じ部署にプログラマが1人でもいる
→ TRUE
1人もいない
→ FALSE
という判定です。
そのため、0人の部署を残したい条件では、単純な EXISTS では落ちてしまいます。
INは「値が候補集合にあるか」を見る
IN は、サブクエリなどで作った値の集合に、対象の値が含まれるかを判定します。
候補集合に部署Aがある
→ TRUE
候補集合に部署Bがない
→ FALSE
つまり、0件の部署がサブクエリの候補集合に現れなければ、その部署は IN では選ばれません。
科目Aでどう出る?
科目Aでは、複数のSQL文から、条件どおりのデータを抽出するものを選ぶ問題として出ます。
このタイプは、SQL全体を一度に読もうとせず、次の順番で見ると整理しやすくなります。
1. 外側は何を候補にしているか
2. 内側は外側の行を参照しているか
3. 内側で何を数えているか
4. 0件のとき何が返るか
5. 最後の比較条件を満たすか
まず「何を数えているか」を確認する
例えば、
SELECT COUNT(*)
FROM 社員 B
WHERE B.部署コード = A.部署コード
AND B.職務 = 'プログラマ'
なら、
同じ部署
+
職務がプログラマ
↓
その人数を数える
です。
一方、
AND B.職務 <> 'プログラマ'
なら、数えているのはプログラマ以外です。
COUNT が書かれているだけで正しいと判断せず、COUNTの前にWHEREで何を残したかを確認します。
「未満」に0が含まれることを確認する
5人未満
→ 0, 1, 2, 3, 4人
5人以下
→ 0, 1, 2, 3, 4, 5人
この違いはSQL以前の条件整理ですが、試験では非常に重要です。
「0人」まで含むなら、
0件のとき、そのSQLはどうなる?
と必ず確認します。
外側の候補集合にも注意する
相関サブクエリが0を返せても、外側の表に候補自体が存在しなければ結果には出ません。
例えば、
FROM 社員 A
から部署コードを出している場合、社員が1人もいない部署は外側に登場しません。
試験では、どの表から候補を取り出しているかも確認します。
どんな場面で使う?
相関サブクエリは、外側の各行について、関連するデータを個別に調べたいときに使えます。
例えば、
- 各部署について、その部署の社員数を調べる
- 各顧客について、その顧客の注文件数を調べる
- 各商品について、その商品の在庫が存在するか調べる
- 各社員について、その社員より給与が高い人がいるか調べる
といった場面です。
イメージは常に、
外側の1行を決める
↓
その値を内側へ渡す
↓
内側で関連データを調べる
↓
条件を満たせば外側の行を残す
です。
実務ではJOINや集計を使って同じ結果を表現できる場合もありますが、FE試験ではまず、相関条件が何を結び付けているかを読めることが重要です。
よくある誤解・混同
COUNTが0なら、その部署は必ず結果に出る
必ずではありません。
COUNT のサブクエリまで到達するには、まず外側の問合せにその候補が必要です。
外側に候補がある
+
内側COUNTが0
→ 0として比較できる
外側に候補自体がない
→ そもそも判定されない
GROUP BY + HAVING COUNT(*) < 5なら0人も含む
そのままでは含まれない場合があります。
先に WHERE 職務='プログラマ' で絞っていると、プログラマ0人の部署には行が残らず、グループ自体が作られません。
COUNTの結果が0
≠
0件のグループが存在する
と切り分けます。
EXISTSの中にCOUNTを書けば0件も判定できる
EXISTS が見るのは、サブクエリが行を返すかどうかです。
集計関数を使うと、書き方によっては0件でも集計結果の1行が返るため、意図と違う判定になることがあります。
試験では、EXISTS を見たらまず、
「何か1行でも存在するか」を判定している
と捉えます。
INと相関サブクエリは同じ
同じ結果を作れる場合はありますが、考え方は違います。
IN
→ 値が候補集合に含まれるか
相関サブクエリ
→ 外側の現在行を使って内側を評価する
SQLの見た目よりも、何を比較・判定しているかを読みます。
まとめ(試験直前用)
- 相関サブクエリは、内側から外側の現在行を参照する
COUNT(*)は、該当行が0件でも 0 を返せるGROUP BYは、元になる行が0件ならグループ自体が作られないEXISTSは「1件でもあるか」、INは「値が候補集合にあるか」を見る- 「5件未満」には 0件も含まれる
- 試験では、何を数えているか・0件のときどうなるか・外側の候補は何かを確認する
0件を含む条件では、「0を返せるか」だけでなく「候補そのものが消えないか」を見る。
公式情報・参考リンク
- PostgreSQL Documentation|Subquery Expressions
- EXISTSやINなど、サブクエリ式の意味を確認できる公式リファレンスです。
- PostgreSQL Documentation|Aggregate Functions
- COUNTなどの集計関数の仕様を確認できます。
- IPA:基本情報技術者試験
- 基本情報技術者試験の公式情報と最新の試験範囲を確認できます。