システムアーキテクト 2021年 午前2 問24
問題文
ある月の“月末商品在庫”表と“当月商品出荷実績”表を使って、ビュー“商品別出荷実績”を定義した。このビューにSQL文を実行した結果の値はどれか。
〔ビュー“商品別出荷実績”の定義〕
CREATE VIEW 商品別出荷実績(商品コード, 出荷実績数, 月末在庫数)
AS SELECT 月末商品在庫.商品コード, SUM(出荷数), 在庫数
FROM 月末商品在庫 LEFT OUTER JOIN 当月商品出荷実績
ON 月末商品在庫.商品コード = 当月商品出荷実績.商品コード
GROUP BY 月末商品在庫.商品コード, 在庫数
〔SQL文〕
SELECT SUM(月末在庫数) AS 出荷商品在庫合計
FROM 商品別出荷実績 WHERE 出荷実績数 <= 300

選択肢
ア:400(正解)
イ:500
ウ:600
エ:700
🔒 解説は解答すると表示されます
SUMとNULLの挙動【午前2解説】
正解の理由
ビューのグループ集計では、各商品ごとに出荷数をSUMしています。SUMはグループ内のNULLを無視し、非NULL値が一つもないグループではSUMはNULLになります。さらに、WHERE句での比較(NULL <= 300)はUNKNOWNとなり除外されます。このため出荷実績が存在しない商品はWHEREで除外されます。個別に計算すると、出荷実績数が300以下となる商品は在庫数100(S001)と300(S003)のみで、その合計は400です。したがって答えは ア(400)となります。
解法ステップ
-
LEFT OUTER JOIN+GROUP BY による各商品の集計値を求める
- S001: 出荷実績数 = 50 + 100 = 150、在庫数 = 100
- S002: 出荷実績なし → 出荷実績数 = NULL、在庫数 = 250
- S003: 出荷実績数 = 150 + 150 = 300、在庫数 = 300
- S004: 出荷実績なし → 出荷実績数 = NULL、在庫数 = 450
- S005: 出荷実績数 = 100 + 250 = 350、在庫数 = 200
-
WHERE 出荷実績数 <= 300 を適用
- NULL <= 300 は UNKNOWN → WHEREで除外 → S002、S004 は除外
- 残る行の判定: S001(150) は true、S003(300) は true、S005(350) は false
-
残った行の月末在庫数をSUM
- 含まれるのは S001 の 100 と S003 の 300 → 合計 400
選択肢別の誤答解説
- ア(400): 正しい。上記手順で得られる値です。
- イ(500): 多くの場合は「NULLを0と見なしてS002やS004を含める」などの誤った前提から生じます。だが実際はNULLは比較で除外されるため、500にはなりません。
- ウ(600): 「S005の出荷実績を誤って300以下と判断して在庫200を含めた(100+300+200=600)」などの出荷数の合算ミスが原因で生じる誤答です。実際のS005は350で除外されます。
- エ(700): 複数の商品の在庫を誤って含める、または集計タイミング(JOIN前後での条件適用)を誤解した結果としてあり得る数字です。正しい評価順(GROUP BY → WHERE はビューの結果に適用)を意識してください。
よくある誤解
- SUMはNULLを0として扱う:誤り。SUMはグループ内のNULLを無視し、非NULL値が一つもなければSUM結果はNULLになります。NULLと数値の比較はUNKNOWNとなりWHEREで除外されます。
- LEFT JOINで必ず左側の行がすべて残ると思い込み、WHEREに条件を書くとその前提が崩れる:LEFT JOINで右側がNULLでもJOIN結果には左の行は出ますが、WHEREで右側カラムに条件をかければその行が除外されることがあります(本問では出荷実績数がNULLだと除外)。
補足コラム
- 出荷実績がない商品を「出荷実績数 = 0」として扱いたい場合はビュー定義やクエリでNULLを0に変換します。例えば SQL(標準)では COALESCE を使います。
SELECT 月末商品在庫.商品コード,
COALESCE(SUM(出荷数), 0) AS 出荷実績数,
在庫数
FROM 月末商品在庫
LEFT OUTER JOIN 当月商品出荷実績
ON 月末商品在庫.商品コード = 当月商品出荷実績.商品コード
GROUP BY 月末商品在庫.商品コード, 在庫数;
こうすると出荷実績がない商品は出荷実績数が0となり、WHERE 出荷実績数 <= 300 に合致します(要件次第で使い分け)。
FAQ
Q. SUMがNULLを返すのはどんなときですか?
A. グループ内に非NULLの値が1つもないときです(例:LEFT JOINで右側に一致行が無く、集計対象列がすべてNULLのとき)。
A. グループ内に非NULLの値が1つもないときです(例:LEFT JOINで右側に一致行が無く、集計対象列がすべてNULLのとき)。
Q. WHERE と HAVING の違いは?
A. WHERE はグルーピング前の行レベルでの絞り込み、HAVING はGROUP BY の後にグループ単位での絞り込みを行います。本問のようにビューに対する WHERE はビューの出力行に適用されます。
A. WHERE はグルーピング前の行レベルでの絞り込み、HAVING はGROUP BY の後にグループ単位での絞り込みを行います。本問のようにビューに対する WHERE はビューの出力行に適用されます。
Q. NULL を条件に使いたい場合の注意点は?
A. 比較演算(=, <= など)で NULL を使うと結果は UNKNOWN となり除外されます。NULLを明示的に扱うには IS NULL / IS NOT NULL を使うか、COALESCEで代替値を与えます。
A. 比較演算(=, <= など)で NULL を使うと結果は UNKNOWN となり除外されます。NULLを明示的に扱うには IS NULL / IS NOT NULL を使うか、COALESCEで代替値を与えます。
関連キーワード: LEFT OUTER JOIN、GROUP BY、SUM、NULL の扱い、WHERE句、COALESCE、集計関数

\ せっかくなら /
システムアーキテクトを
クイズ形式で学習しませんか?
クイズ画面へ遷移する→
すぐに利用可能!

