基本情報技術者 2016年 秋期 午前(科目A) 問29
問題文
“社員”表と“部門”表に対して、次のSQL文を実行したときの結果はどれか。
SELECT COUNT(*) FROM 社員, 部門
WHERE 社員.所属部門 = 部門.部門名 AND 部門.フロア = 2

選択肢
ア:1
イ:2
ウ:3(正解)
エ:4
🔒 解説は解答すると表示されます
結合結果の行数【午前解説】
正解の理由
SQL文は社員表と部門表を等値結合し、部門のフロアが2である行だけを残した結果の行数を数えています。部門表でフロアが2の部門は「情報システム」「経理」「法務」「購買」の4件ですが、社員表に所属として登録されているのは「情報システム」2名と「経理」1名の合計3名です。内部結合(カンマ区切り+WHERE の等値条件)は該当する社員ごとに部門行と結合するため、結果行数は該当社員数と一致します。したがって正解は ウ(3)です。
(補足)COUNT(*) は結果セットの行数を数えます。NULL の有無に関係なく行数をカウントする点を念頭に置いてください。
解法ステップ
- 部門表からフロア = 2 の部門名を抽出する
→ 情報システム、経理、法務、購買(4件) - 社員表の所属が上記部門名と等しい社員を探す
→ 情報システム:11005、12002(2名)/経理:11002(1名)/法務・購買:該当なし - 等値結合の結果行は該当社員ごとに1行ずつ生成されるので合計 = 2 + 1 = 3
- COUNT(*) はその結果行の総数を返す → 3
選択肢別の誤答解説
- ア: 1 を選ぶ誤り
法務や購買に社員がいない点を見落とし「フロア2の部門のうち1つだけが該当」と誤解するとこの答えになる可能性がありますが、実際は情報システムと経理に社員が存在します。 - イ: 2 を選ぶ誤り
情報システムの社員2名のみを数えて経理を見落とした場合に起こります。所属欄に経理が1名いることを確認してください。 - ウ: 3(正答)
社員ごとに結合される点と COUNT(*) の挙動(結果行数を数える)を正しく理解したケースです。 - エ: 4 を選ぶ誤り
部門表でフロア2の部門が4件であることと COUNT() の結果を混同すると起こります。COUNT() は結合結果の行数を数えるため、部門の件数そのままにはなりません(該当社員がいない部門は結合で行を作りません)。
よくある誤解
- COUNT() は NULL を除外する:誤りです。COUNT() は結果セットの全行をカウントします。一方、COUNT(列名) はその列が NULL でない行を数えます。
- 部門の件数=結果行数と思い込む:内部結合では「社員 × 部門」の組合せが行となるため、部門側の件数だけを見ても結果行数はわかりません。実際にマッチする社員数を数える必要があります。
- カンマ区切りの結合が常に全行を掛け合わせる(Cartesian product)と理解する:カンマ+WHERE の等値条件は内部結合と同等で、WHERE で絞られる場合は Cartesian product にはなりません。
補足コラム
- 等価な書き方(可読性向上):
SELECT COUNT(*)
FROM 社員
JOIN 部門 ON 社員.所属部門 = 部門.部門名
WHERE 部門.フロア = 2;
- COUNT の各種使い分け:
- COUNT(*):全行を数える(NULL 関連なし)
- COUNT(列名):その列が NULL でない行を数える
- COUNT(DISTINCT 列名):重複を除いた値の個数を数える
- 内部結合では、片方に該当が無ければその組合せは生成されません(LEFT/RIGHT JOIN と対比して理解すると誤解が減ります)。
FAQ
Q. 社員表の所属列に NULL があったらどうなる?
A. 等値条件で NULL は等しく比較されないため、該当行は結合条件を満たさず結果には現れません。ただし COUNT(*) は結果セットの行数を数えるので、結合で生成された行があればそれを全て数えます。
A. 等値条件で NULL は等しく比較されないため、該当行は結合条件を満たさず結果には現れません。ただし COUNT(*) は結果セットの行数を数えるので、結合で生成された行があればそれを全て数えます。
Q. 部門名が重複していたらどう数える?
A. 重複する部門名が部門表にあれば、該当社員は重複分だけ複数行と結合されます(多対多の増殖が起きる)。結果行数はその実際の組合せ数になります。
A. 重複する部門名が部門表にあれば、該当社員は重複分だけ複数行と結合されます(多対多の増殖が起きる)。結果行数はその実際の組合せ数になります。
Q. 「GROUP BY 部門名」で集計すればよい場面は?
A. 部門ごとの社員数を知りたい場合は GROUP BY 部門名 と COUNT(*) を併用します。本問は全体の件数だけを求めているため不要です。
A. 部門ごとの社員数を知りたい場合は GROUP BY 部門名 と COUNT(*) を併用します。本問は全体の件数だけを求めているため不要です。
関連キーワード: SQL、COUNT(*)、等値結合、内部結合、NULL、集計関数、JOIN、COUNT(DISTINCT)

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

