データベーススペシャリスト 2010年 午前2 問14
問題文
“製品”表と “在庫” 表に対し、次の SQL文を実行した結果として得られる表の行数は幾つか。
SELECT DISTINCT 製品番号 FROM 製品
WHERE NOT EXISTS (SELECT 製品番号 FROM 在庫
WHERE 在庫数 > 30 AND 製品.製品番号 = 在庫.製品番号)

選択肢
ア:1
イ:2(正解)
ウ:3
エ:4
🔒 解説は解答すると表示されます
NOT EXISTSの除外検索【午前2解説】
正解の理由
このSQLは、製品表の各製品番号に対して「在庫表に該当製品で在庫数が30より大きい行が存在するか」を確認し、存在する製品を除外しています。該当製品について調べると、在庫表に一件も存在しない製品(MZ1000)と、存在するが全ての在庫行が在庫数 <= 30 の製品(XZ3000)の2件が「在庫数 > 30 の行が存在しない」ため残ります。したがって、選択肢イ(2行)が正解です。
解法ステップ
-
クエリの意味を把握する
- 外側:製品表から製品番号を取得(DISTINCT で重複排除)。
- 内側(相関サブクエリ):同一製品番号かつ在庫数 > 30 の在庫行が存在するかをチェック。
- NOT EXISTS により、内側の条件を満たす行が一つも無い製品だけを外側に残す。
-
製品ごとに内側の有無を判定する
- AB1805:在庫に 150 がある → 在庫数 > 30 の行が存在 → 除外
- CC5001:在庫に 200 や 40 がある → 存在 → 除外
- MZ1000:在庫に該当行なし → 存在しない → 残る
- XZ3000:在庫は 30 と 20(どちらも >30 ではない) → 存在しない → 残る
- ZZ9900:在庫に 130 がある → 存在 → 除外
-
残った製品番号は2件(MZ1000, XZ3000)なので結果の行数は2行。
選択肢別の誤答解説
-
ア(1)
- 単に在庫が存在しない製品のみを数えた誤り。XZ3000のように在庫はあるが全て <= 30 の製品も含める必要がある点を見落としている。
-
ウ(3)
- 在庫数の判定で「>= 30」と誤解している可能性。またはDISTINCTの扱いにより重複を数えてしまった誤り。実際は 30 は除外条件(>30)に該当しない。
-
エ(4)
- 在庫数の合計を見て判定した誤り(例:複数倉庫の合計が30を超えるかで判断)。クエリは個々の在庫行の値を基準に判定するため合計は関係ない。
よくある誤解
- 「在庫が一件もない製品は外れる」と思う誤解:逆に在庫行が無ければ内側サブクエリは空になり NOT EXISTS が真となるため外側に残ります。
- 「30は含まれる」と考える誤解:条件は在庫数 > 30 なので在庫数がちょうど30の行は除外条件になりません(=存在しない扱い)。
- NOT EXISTS と NOT IN を同義と考える誤解:NULL を含むデータを扱う場合に挙動が異なるので注意が必要です。
補足コラム
- 相関サブクエリ(ここでは製品.製品番号 を参照)は外側の行ごとに評価され、内側で「該当する行が見つかった時点」で評価を打ち切る実装が多く効率的です。
- このクエリは等価に次のようなLEFT JOIN+IS NULL/条件で表現できますが、論理やNULLの扱いで差が出るケースもあるため意図に合わせて選ぶとよいでしょう。
-- 例:LEFT JOINを使った別解(参考)
SELECT DISTINCT p.製品番号
FROM 製品 p
LEFT JOIN 在庫 z
ON p.製品番号 = z.製品番号 AND z.在庫数 > 30
WHERE z.製品番号 IS NULL;
FAQ
Q. 在庫が無い製品は出力されるのか?
A. はい。在庫表に該当行が全く無ければ内側は空になり NOT EXISTS が真となるため出力されます。
A. はい。在庫表に該当行が全く無ければ内側は空になり NOT EXISTS が真となるため出力されます。
Q. DISTINCT は結果に影響するか?
A. 今回の製品表は製品番号が一意なので影響しません。ただし製品表に重複がある場合は重複排除の役割を果たします。
A. 今回の製品表は製品番号が一意なので影響しません。ただし製品表に重複がある場合は重複排除の役割を果たします。
Q. 条件を >= に変えたらどうなるか?
A. 在庫数がちょうど30の行を「存在する」とみなすため XZ3000 は除外され、結果行数が変わります。
A. 在庫数がちょうど30の行を「存在する」とみなすため XZ3000 は除外され、結果行数が変わります。
関連キーワード: SQL、NOT EXISTS、相関サブクエリ、SELECT DISTINCT、LEFT JOIN、NULL取り扱い

\ せっかくなら /
データベーススペシャリストを
クイズ形式で学習しませんか?
クイズ画面へ遷移する→
すぐに利用可能!

