ホーム > データベーススペシャリスト試験 > 2011年

データベーススペシャリスト試験 2011年 午前205


“社員番号” と “氏名” を列としてもつR表とS表に対して, 差 (R-S) を求めるSQL 文はどれか。ここで, R 表とS 表の主キーは“社員番号”であり, “氏名”は“社員番号”に関数従属する。
SELECT R.社員番号, S.氏名 FROM R, S
  WHERE R. 社員番号 <> S. 社員番号
SELECT 社員番号, 氏名 FROM R
  UNION SELECT 社員番号, 氏名 FROM S
SELECT 社員番号, 氏名 FROM R
  WHERE NOT EXISTS (SELECT FROM S
    WHERE R. 社員番号 = S. 社員番号)
(正解)
SELECT 社員番号, 氏名 FROM S
  WHERE S.社員番号 NOT IN (SELECT 社員番号 FROM R
    WHERE R.社員番号= S.社員番号)

解説

解説:R表とS表の差集合 (R - S) を求めるSQL文について


問題の内容整理

  • R表S表 はそれぞれ、
    • 列: 社員番号氏名 を持つ
    • 主キーは 社員番号
    • 氏名社員番号 に関数従属(すなわち社員番号が一意に氏名を決定)
  • 求めたいのは、R表に存在するがS表には存在しないレコードの集合(差集合 R - S)

SQLで差集合を表現する方法

  • 差集合 (R - S) とは、
    「Rに含まれているが、Sには含まれていない」レコードを選ぶこと。
  • 主キーが社員番号であるため、差集合の判定は社員番号を基準に行うのが適切。

選択肢の検証

ア:

SELECT R.社員番号, S.氏名 FROM R, S
WHERE R.社員番号 <> S.社員番号
  • 効率的に差集合を求める意図とは異なる。
  • 条件は「Rの社員番号とSの社員番号が異なる組のすべての組み合わせ」を選択しており、
    Rにしかない行を正確に抽出できない。
  • 【誤り】

イ:

SELECT 社員番号, 氏名 FROM R
UNION SELECT 社員番号, 氏名 FROM S
  • これは 和集合 のSQL文。
  • RとSのすべての社員を重複なく取得。
  • 差集合ではない。
  • 【誤り】

ウ:

SELECT 社員番号, 氏名 FROM R
WHERE NOT EXISTS (SELECT FROM S
                  WHERE R.社員番号 = S.社員番号)
  • Rの中で、Sに同じ社員番号が存在しないものを取得。
  • 主キーの社員番号を基準に比較しているため、氏名の不整合等は考慮不要。
  • 正しくR-S(差集合)を表現している。
  • 【正解】

エ:

SELECT 社員番号, 氏名 FROM S
WHERE S.社員番号 NOT IN (SELECT 社員番号 FROM R
                         WHERE R.社員番号 = S.社員番号)
  • Sから差集合を求めている(S - R)。
  • 質問はR - Sなので逆方向。
  • 【誤り】

まとめ

  • 差集合 R - S は、
    R に存在し、S には存在しない社員を主キー(社員番号)で判定して抽出すること。
  • 選択肢ウのSQL文は、
    WHERE NOT EXISTS とサブクエリを使用し、Rの社員番号がSに存在しない場合のみ抽出している。
    この文が正解となる。

追加説明:NOT EXISTSNOT IN の違い

  • NOT EXISTS はサブクエリの存在チェックに適し、NULLによる副作用の影響を受けにくい。
  • 一方、NOT IN はサブクエリにNULLがあると動作が変わりやすいので注意が必要。
  • この問題では主キー(社員番号)はNULLにならない前提なので動作上大きな差はないが、一般的に差集合には NOT EXISTS が安全で推奨される。

以上の理由により、正解はウ となります。
← 前の問題へ次の問題へ →

©︎2025 情報処理技術者試験対策アプリ