応用情報技術者 2017年 秋期 午前2 問28
問題文
関係R (ID, A, B, C)の A,Cへの射影の結果と SQL文で求めた結果が同じになるように、a に入れるべき字句はどれか。ここで、関係Rを表Tで実現し、表Tに各行を格納したものを次に示す。

選択肢
ア:ALL
イ:DISTINCT(正解)
ウ:ORDER BY
エ:REFERENCES
🔒 解説は解答すると表示されます
射影の重複排除【午前2解説】
正解の理由
関係代数における射影(ある属性のみを取り出す操作)は集合としての結果を返すため、重複する組は1件にまとめられます。SQL の標準的な SELECT は多重集合(バグ、bag)として結果を返すため、重複を取り除くには明示的に DISTINCT を付ける必要があります。したがって、A, C への射影と SQL の結果を一致させるには イ(DISTINCT)を使う必要があります。
解法ステップ
- 表 T の各行について A と C の組を列挙する(そのまま SELECT A, C FROM T を実行した場合の出力を想定)。
- 列挙した組の中で重複している組があるか確認する(例えば (a1, c1) が複数ある)。
- 関係代数の射影は集合で重複を除くので、SQL でも重複排除を行うキーワードを選ぶ必要がある。
- 重複排除を行う SQL のキーワードは DISTINCT。よって空欄には DISTINCT を入れる。
実際のデータで確認すると、T から (A, C) を取り出すと
- (a1, c1)
- (a1, c2)
- (a1, c1) ← 重複
- (a2, c2)
- (a2, c2) ← 重複
集合としては (a1, c1), (a1, c2), (a2, c2) の3件になるため、DISTINCT が必要です。
選択肢別の誤答解説
-
ア: ALL
SELECT ALL は明示的に書かなくても SQL のデフォルト動作であり、重複を削除しません。従って多重集合のままになり、射影の集合結果と一致しません。 -
イ: DISTINCT
正答。出力の重複行を取り除き、関係代数の射影と同様の集合を返します。 -
ウ: ORDER BY
結果をソートするための句であり、重複を除去しません。ORDER BY は行の順序を変更するだけで、集合化は行いません。 -
エ: REFERENCES
REFERENCES は外部キー制約の宣言などに使うDDL要素であり、SELECT 文の中で結果の重複制御には関係ありません。
よくある誤解
- 「SELECT は集合を返す」と覚えていることがあるが誤りです。SQL は通常多重集合(重複を保持)を返します。集合的振る舞いを期待する場合は DISTINCT を使う必要があります。
- DISTINCT は各列ごとに個別に作用するのではなく、SELECT に列挙した全列の組合せで重複を判定します(A と C を両方見て同一か判断する)。
補足コラム
- DISTINCT と同様の効果は GROUP BY を使っても得られます(例: SELECT A, C FROM T GROUP BY A, C)。内部実装や最適化の違いで性能が変わることがありますので、大量データでは実行計画やインデックスを確認してください。
- NULL 値については、SQL の DISTINCT は複数の NULL を同一視して重複として扱います(結果上は1件にまとめられる)。ただし実装差や条件による微妙な振る舞いに注意してください。
例(動作確認用 SQL):
-- 重複あり(多重集合)
SELECT A, C FROM T;
-- 重複を除去(集合)
SELECT DISTINCT A, C FROM T;
FAQ
Q. DISTINCT はどの列に対して効くのですか?
A. SELECT に指定した全列の組合せに対して効きます。ある列だけ重複を除きたい場合は別途集約関数やサブクエリを使います。
A. SELECT に指定した全列の組合せに対して効きます。ある列だけ重複を除きたい場合は別途集約関数やサブクエリを使います。
Q. ORDER BY を付ければ重複が除かれると思っていたのですが?
A. いいえ。ORDER BY はソート専用で、重複除去の機能はありません。重複を除きたいときは DISTINCT または GROUP BY を使ってください。
A. いいえ。ORDER BY はソート専用で、重複除去の機能はありません。重複を除きたいときは DISTINCT または GROUP BY を使ってください。
関連キーワード: SELECT DISTINCT、射影、集合と多重集合、GROUP BY、重複排除、SQL文法

\ せっかくなら /
応用情報技術者を
クイズ形式で学習しませんか?
クイズ画面へ遷移する→
すぐに利用可能!

