戦国IT - 情報処理技術者試験の過去問対策サイト
ブログお知らせお問い合わせ料金プラン

データベーススペシャリスト 2012年 午前209


問題文

ある月の“月末商品在庫”表と“当月商品出荷実績”表を使って、ビュー“商品別出荷実績”を定義した。このビューにSQL文を実行した結果の値はどれか。
データベーススペシャリスト 2012年 午前2 問09の問題画像

選択肢

400(正解)
500
600
700

🔒 解説は解答すると表示されます

LEFT JOINのNULL扱い【午前2解説】

正解の理由

ビューの各行は「商品コードごとの出荷実績合計(SUM)」と月末在庫数を持ちます。各商品の出荷合計は次のとおりで、S002とS004は該当する出荷行がないため出荷実績数がNULLになります。
  • S001: 50 + 100 = 150
  • S002: NULL(出荷なし)
  • S003: 150 + 150 = 300
  • S004: NULL(出荷なし)
  • S005: 100 + 250 = 350
WHERE句の条件「出荷実績数 <= 300」はNULLに対する比較ではUNKNOWN(偽扱い)になり、NULL行は除外されます。したがって条件を満たすのは出荷実績数が150のS001と300のS003だけで、月末在庫の合計は 100 + 300 = 400 となります。以上より選択肢が正しいです。

解法ステップ

  1. ビュー定義のSELECT句で商品ごとにSUM(出荷数)を算出する。LEFT OUTER JOIN により、右側に該当行がなければ右側列はNULLとなる。
  2. 各商品について出荷実績数を計算する(上記の合計値を参照)。
  3. ビューに対する外側のSELECTでWHERE 出荷実績数 <= 300 を適用する。ここでNULL <= 300 は UNKNOWN となるため除外される。
  4. WHEREで残った行(S001, S003)の月末在庫数をSUMして答えを求める:100 + 300 = 400。

選択肢別の誤答解説

  • ア(400)
    正しい理由は上記のとおり。S002/S004はNULLで除外、S001とS003のみを合算するため400になる。
  • イ(500)
    500は「S003(300) + S005(200)」を合算した値です。これを選ぶ誤りは、S005の出荷合計(実際は350)を誤って0または未処理と見なして条件を通してしまったケースや、S001を誤って除外した計算ミスによるものです。実データではS005は350で条件を満たさないため誤りです。
  • ウ(600)
    600は「S001(100) + S003(300) + S005(200)」の合算に相当します。これはS005の出荷合計を誤って250または0と見なしてしまう誤り(出荷数の合計ミス)で生じます。実際にはS005の出荷合計は350で条件を満たしません。
  • エ(700)
    700は「S002(250) + S004(450)」を合算した値に相当します。これはSUMがNULLを0扱いして未出荷の商品を条件に通してしまった(NULL→0の誤認)場合に生じる典型的な誤りです。SQLの比較ではNULLは0とは扱われないため、この解釈は間違いです。

よくある誤解

  • SUMの結果が「0」になると誤解する
    LEFT JOINで一致しない右側列があるとき、SUMは非NULL値がなければNULLを返します(0ではない)。NULLと数値の比較はUNKNOWNになり条件に合致しない点を取り違えやすいです。
  • WHEREとHAVINGの役割混同
    集約後の条件はHAVINGで評価するのが原則と理解する人がいます。今回はビューに既に集約列があるため外側のWHEREでその列を比較できますが、集約結果に対するフィルタリングのタイミングとNULL扱いを混同すると誤答になります。
  • NULL比較の扱いを忘れる
    「NULL <= 300 を偽とする」ことを忘れ、NULLを条件に合致すると誤認するミスが多いです。

補足コラム

該当ケースで「出荷実績が無ければ0扱いして条件に含めたい」場合は、ビューやクエリでNULLを0に変換すると意図どおりになります。例:
-- ビュー定義を変える例(NULLを0に置換)
CREATE VIEW 商品別出荷実績2 AS
SELECT
  m.商品コード,
  COALESCE(SUM(t.出荷数), 0) AS 出荷実績数,
  m.在庫数
FROM 月末商品在庫 m
LEFT JOIN 当月商品出荷実績 t
  ON m.商品コード = t.商品コード
GROUP BY m.商品コード, m.在庫数;
あるいは、ビューはそのままにして外側のクエリでCOALESCEを使う方法もあります。また、集約結果に対する条件を直接書く場合はHAVING句を用いるのが設計上明確です。

FAQ

Q: SUMがNULLを返すのはなぜですか?
A: グループ内に非NULLの値が1件もない場合、SUMはNULLになります(NULLは集計対象から除外されるため)。したがって「該当行なし=0」とは自動的に扱われません。
Q: NULLを0扱いにしたいときはどうする?
A: COALESCE(SUM(...), 0) のようにNULLを明示的に0に変換してください。ビュー定義内でも外側のクエリでも適用可能です。
Q: WHEREとHAVINGの違いは?
A: WHEREは行単位のフィルタ(グループ化の前)に使い、HAVINGはGROUP BYで作られたグループに対する条件(集約後)に使います。本問ではビューに集約列があるため外側のWHEREで参照していますが、集約直後に条件を付けたい場合はHAVINGが適切です。

関連キーワード: LEFT OUTER JOIN、SUM、NULL扱い、COALESCE、HAVING、GROUP BY、集計結果のフィルタリング
← 前の問題へこの年度をクイズで解く次の問題へ →
戦国ITクイズ機能

\ せっかくなら /

データベーススペシャリスト
クイズ形式で学習しませんか?

クイズ画面へ遷移する

すぐに利用可能!

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

このサイトについてブログプライバシーポリシー利用規約特商法表記開発者について