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

データベーススペシャリスト 2017年 午前210


問題文

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

選択肢

400(正解)
500
600
700

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

ビューの集計とNULL処理【午前2解説】

正解の理由

ビュー側で各商品ごとの出荷合計(出荷実績数)を算出すると、出荷実績のない商品は集計結果がNULLになります。外側のSELECT句で使われている WHERE 出荷実績数 <= 300 は、ビューが返す集計結果に対する比較であり、NULL と比較した場合は真にならないため除外されます。したがって出荷実績数が数値として評価される商品だけが残り、それらの月末在庫数を合計します。該当するのは S001(出荷実績150、在庫100)と S003(出荷実績300、在庫300)で、月末在庫数の合計は となり、選択肢のうち に一致します。

解法ステップ

  1. ビュー定義の処理を想起する:LEFT OUTER JOIN と GROUP BY により、月末商品在庫の全行ごとに SUM(出荷数) を算出する。出荷が無い行の SUM は NULL。
  2. 各商品の出荷実績数を求める:
    • S001: 50 + 100 = 150
    • S002: 該当行なし → SUM = NULL
    • S003: 150 + 150 = 300
    • S004: 該当行なし → SUM = NULL
    • S005: 100 + 250 = 350
  3. 外側クエリの WHERE 句(出荷実績数 <= 300)を適用する。NULL と比較した行(S002、S004)は除外される。残るのは S001 と S003。
  4. 残った行の月末在庫数を合計する:

選択肢別の誤答解説

  • ア(400)
    正しい。上記の通り、数値として比較可能な行は S001 と S003 のみで、在庫合計は
  • イ(500)
    誤り。500 は例えば S003(300)と S005(200)を合算した値に相当しますが、本問では S005 の出荷実績は 350 であり 350 <= 300 は偽なので S005 は除外されます。S005 を誤って条件に含めるか、S001 を除外するなどの計算ミスが原因でこの値が出ます。
  • ウ(600)
    誤り。600 は S001(100)+S003(300)+S005(200) の合算に見える値ですが、S005 は実際の在庫200でも出荷実績350のため条件を満たさず除外されます。出荷実績の判定ミスで発生する誤答です。
  • エ(700)
    誤り。700 は S002(250)+S004(450) の合算です。これは SUM が存在しない(NULL)行を 0 とみなして WHERE (0 <= 300) を満たすと誤解した場合に得られ得る値ですが、標準SQLでは SUM が行なしで NULL になり、NULL <= 300 は UNKNOWN(偽扱い)となり除外されます。

よくある誤解

  1. 「SUM が行がなければ 0 になる」
    実際は標準SQLの集計関数 SUM は該当行が無ければ NULL を返します(COALESCE 等で 0 に変えなければならない)。NULL と比較すると条件は真になりません。
  2. 「WHERE は集計後に効く」
    単一の SELECT 内では WHERE は GROUP BY 前に適用され、HAVING が集計後の条件に使われます。ただし本問の WHERE は外側クエリであり、ビュー(集計済み結果)に対するフィルタなので集計後の行に作用します。この点を混同しやすいので注意してください。
  3. 「LEFT JOIN で NULL は自動的に 0 になる」
    LEFT JOIN により右側の列が NULL になることはあるが、それを 0 とみなすのはデータベースが自動で行う処理ではありません。明示的に置換が必要です。

補足コラム

出荷実績がない商品も「出荷実績数 = 0」として扱いたい場合は、ビュー定義で NULL を 0 に置換しておくと便利です。例えば次のように COALESCE(または DBMS により NVL)を使います。
CREATE VIEW 商品別出荷実績 AS
SELECT
  m.商品コード,
  COALESCE(SUM(t.出荷数), 0) AS 出荷実績数,
  m.在庫数
FROM
  月末商品在庫 m
  LEFT OUTER JOIN 当月商品出荷実績 t
    ON m.商品コード = t.商品コード
GROUP BY
  m.商品コード, m.在庫数;
このようにしておけば外側の WHERE で 0 <= 300 を満たす行も残り、条件に含めたいか否かを意図的に制御できます。
また、同じクエリを1つのSELECTで書く場合、集計後の条件は HAVING を使う点を覚えておいてください。

FAQ

Q1: SUM が NULL になるかどうかは DBMS による違いがありますか?
A1: 標準SQLでは集計対象行が無ければ NULL を返します。主要な商用・オープンソースDBでも同様です。動作に依存する振る舞いが心配なら COALESCE で明示的に扱ってください。
Q2: WHERE を HAVING に変えればどうなりますか?
A2: 同じSELECT内で集計結果に条件をかけたい場合は HAVING を使います。ビューを既に使っている場合、外側の WHERE はビューの結果に作用するため、実務ではどちらを使うかは構造によります。
Q3: NULL を 0 にする別の方法はありますか?
A3: COALESCE(SUM(...), 0) の他、DBMS 固有の NVL(Oracle)や IFNULL(MySQL)などがあります。

関連キーワード: SQL、LEFT OUTER JOIN、SUM、NULL、COALESCE、GROUP BY、WHERE、HAVING、集計順序
← 前の問題へこの年度をクイズで解く次の問題へ →
戦国ITクイズ機能

\ せっかくなら /

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

クイズ画面へ遷移する

すぐに利用可能!

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

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