SQL / LESSON 05 / SQL05

SQL:NULL の扱い

1学習の目的

2基礎解説

NULL は「値が入っていない」という状態です。0でも空文字でもなく、「不明」を表します。

⚠ この章からテーブルにデータを2件追加します

下のSQLを実行環境で流してから始めてください。SQL01〜04の問題を解き直すと件数が変わりますが、それが正しい動作です(実務でもデータは日々増えます)。

INSERT INTO products VALUES
 (6, '新商品A',    NULL,   25000, NULL),
 (7, 'サンプル品', '周辺機器', NULL,    3);
idnamecategorypricestock
6新商品ANULL25000NULL
7サンプル品周辺機器NULL3
やりたいこと正しい書き方誤り
NULLを探すWHERE price IS NULL= NULL
NULLでないものを探すWHERE price IS NOT NULL<> NULL
NULLを別の値に置き換えるCOALESCE(price, 0)
NULLでない件数を数えるCOUNT(price)
✅ 覚えるべき重要ポイント
  1. = NULL は絶対に一致しない。NULLは「不明」なので、「不明 = 不明」が真になるとは限らないという考え方。エラーは出ず、静かに0件が返る
  2. 判定は必ず IS NULL / IS NOT NULL。この2つだけが NULL を正しく扱える。
  3. NULLは通常の条件から漏れるWHERE price > 10000 でも WHERE price <= 10000 でも、priceがNULLの行はどちらにも入らない
  4. NULLを含む計算はすべてNULLになるNULL * 3NULL + 100 も結果はNULL。集計が合わない原因の多くはこれ。
  5. COUNT(*) は全行を数えるが、COUNT(列名)その列がNULLでない行だけを数える。この違いを知らないと件数がずれる。

現場使用例:未入力の項目を探す、退会日が未設定=現役会員の抽出、金額未確定の注文の検出、欠損データの補完。実データにNULLが無いことはまずない

-- ❌ これは0件になる(エラーにもならない)
SELECT name FROM products WHERE category = NULL;

-- ✅ 正しい書き方
SELECT name FROM products WHERE category IS NULL;

-- NULLでないものだけ
SELECT name FROM products WHERE price IS NOT NULL;

-- ⚠ NULLは条件から漏れる
SELECT name FROM products WHERE price > 10000;
-- → priceがNULLのサンプル品は出てこない

-- NULLを別の値に置き換える
SELECT name, COALESCE(category, '未分類') AS 分類
FROM products;

-- COUNT の違い
SELECT
  COUNT(*)     AS 全行数,      -- 7
  COUNT(price) AS 価格あり;     -- 6(NULLを除く)
FROM products;

3基本ドリル(10問)

SQL05-D01 category が NULL の商品の name を取り出すSQLを書け。 コーディング★☆☆無料
期待される結果

1行。新商品A

ヒント

WHERE category IS NULL と書く。= は使えない。

模範解答
SELECT name
FROM products
WHERE category IS NULL;
解説

NULLの判定は IS NULL だけ。= を使うとエラーも出ずに0件が返るので、間違いに気づきにくい。

SQL05-D02 WHERE category = NULL と書くとどうなるか。
A. NULLの行が返る B. 0件になる C. 全件返る D. エラーになる
選択★☆☆無料
期待される結果

解答 == B

ヒント

NULLは「不明」。不明どうしを = で比べると。

模範解答
B
解説

エラーにならず静かに0件が返るのが最も危険な点。「NULLのデータが1件も無い」と誤解したまま進んでしまう。

SQL05-D03 price が NULL ではない商品の name と price を取り出すSQLを書け。 コーディング★☆☆無料
期待される結果

6行。サンプル品を除く全商品

ヒント

WHERE price IS NOT NULL と書く。

模範解答
SELECT name, price
FROM products
WHERE price IS NOT NULL;
解説

データが揃っている行だけで集計したいときの定番。IS NOT NULL で欠損行を除いてから計算する。

SQL05-D04 在庫が未設定(NULL)の商品を探すSQLを完成させよ。 穴埋め★☆☆無料
コード
SELECT name
FROM products
WHERE stock ____ NULL;
期待される結果

1行。新商品A

ヒント

NULLの判定に使う2語。「〜である」を意味する動詞から始まる。

模範解答
IS
解説

IS は NULL 専用の比較。数値や文字列の比較には使えないので、用途が完全に分かれている。

SQL05-D05 NULL に * 3 を掛けると結果はどうなるか。
A. 0 B. 3 C. NULL D. エラー
選択★☆☆無料
期待される結果

解答 == C

ヒント

「不明な数」を3倍しても、答えは。

模範解答
C
解説

NULLを含む計算はすべてNULLになる。合計や平均が想定と違うとき、まずこれを疑う。

SQL05-D06 category が NULL の場合に「未分類」と表示するSQLを書け。name と、置き換えた分類(別名 cat)を取り出すこと。 コーディング★★☆無料
期待される結果

7行。新商品Aが 未分類

ヒント

COALESCE(列, 代わりの値) を使う。

模範解答
SELECT name, COALESCE(category, '未分類') AS cat
FROM products;
解説

COALESCE は「最初にNULLでない値」を返す関数。画面に「NULL」と表示せず、意味のある文字に置き換えるのに使う。

SQL05-D07 price が NULL のとき 0 として扱い、税込価格を計算するSQLを完成させよ。 穴埋め★★☆無料
コード
SELECT name, ____(price, 0) * 1.1 AS tax_price
FROM products;
期待される結果

7行。サンプル品が 0.0

ヒント

NULLを別の値に置き換える関数。8文字。

模範解答
COALESCE
解説

NULLのまま計算するとNULLになるので、先に0に置き換えてから計算する。金額の集計で欠損を0として扱いたいときの定番。

SQL05-D08 COUNT(*)COUNT(price) の違いは何か。
A. 同じ B. COUNT(price) はNULLを除いて数える C. COUNT(*) のほうが遅い D. COUNT(price) は合計を返す
選択★★☆無料
期待される結果

解答 == B

ヒント

列名を指定したとき、NULLはどう扱われるか。

模範解答
B
解説

COUNT(*) は7、COUNT(price) は6になる。「入力済みの件数」を数えたいときは列名を指定する。この違いを知らないと件数がずれる。

SQL05-D09 price が NULL の商品と、価格が 10000円未満の商品を両方取り出すSQLを書け。name と price を表示すること。 コーディング★★☆無料
期待される結果

4行。マウス / キーボード / USBメモリ / サンプル品

ヒント

OR で2つの条件をつなぐ。NULLは price < 10000 に入らないので、明示的に拾う必要がある。

模範解答
SELECT name, price
FROM products
WHERE price IS NULL
   OR price < 10000;
解説

NULLは条件から漏れるので、必要なら明示的に拾う。「安い商品、または価格未定の商品」という現実的な要求はこの形になる。

SQL05-D10 category と stock の両方が入力されている商品の name・category・stock を取り出すSQLを書け。 コーディング★★☆無料
期待される結果

6行。新商品A(categoryとstockがNULL)だけが除外される

ヒント

IS NOT NULL を AND でつなぐ。

模範解答
SELECT name, category, stock
FROM products
WHERE category IS NOT NULL
  AND stock IS NOT NULL;
解説

複数の列の欠損をまとめて除く形。データ分析の前処理で「完全なデータだけを対象にする」ときによく書く。

4実践シナリオ(5問)

SQL05-S01 【入力漏れの洗い出し】category か price のどちらかが未入力の商品を、name・category・price で取り出すSQLを書け。 コーディング★★☆無料
期待される結果

3列2行。新商品A / サンプル品

ヒント

OR で2つの IS NULL をつなぐ。

模範解答
SELECT name, category, price
FROM products
WHERE category IS NULL
   OR price IS NULL;
解説

データの品質チェックそのもの。マスタ登録の直後にこれを流して、入力漏れを担当者に差し戻すのが実務の運用。

SQL05-S02 【欠損を埋めた一覧】name と、分類(NULLなら「未分類」)と、在庫(NULLなら 0)を、それぞれ別名 cat・stk で取り出すSQLを書け。 コーディング★★☆無料
期待される結果

3列7行。新商品Aが 未分類 / 0

ヒント

COALESCE を2箇所で使う。文字列には文字列、数値には数値を指定する。

模範解答
SELECT
  name,
  COALESCE(category, '未分類') AS cat,
  COALESCE(stock, 0) AS stk
FROM products;
解説

画面に「NULL」と出さないための処理。ユーザーに見せる一覧では、欠損を意味のある表示に置き換えるのが親切。

SQL05-S03 【価格未定の商品】price が 未設定の商品について、name と category と、「価格未定」という固定の文字列(別名 status)を取り出すSQLを書け。 コーディング★★☆無料
期待される結果

3列1行。サンプル品 / 周辺機器 / 価格未定

ヒント

SELECT に文字列をそのまま書ける。'価格未定' AS status のように。

模範解答
SELECT name, category, '価格未定' AS status
FROM products
WHERE price IS NULL;
解説

SELECT には固定の値も書ける。列から取るのではなく、その場で決めた文字列を全行に付けられる。区分やラベルを付けたいときに使う。

SQL05-S04 【在庫金額の安全な計算】在庫金額(price × stock)を計算する。ただしprice か stock が NULL の場合は 0 として扱うこと。name と在庫金額(別名 stock_value)を、在庫金額の大きい順に取り出すSQLを書け。 コーディング★★★無料
期待される結果

2列7行。ノートPC 640000 が先頭、新商品Aとサンプル品は 0

ヒント

COALESCE を両方の列に適用してから掛ける。並べ替えは ORDER BY stock_value DESC。

模範解答
SELECT name, COALESCE(price, 0) * COALESCE(stock, 0) AS stock_value
FROM products
ORDER BY stock_value DESC;
解説

COALESCE を挟まないと、2件がNULLになって並べ替えの結果も変わる。「欠損は0として扱う」という業務ルールを、そのままSQLに落とし込んでいる。

SQL05-S05 【データ充足率の確認】次の4つを1行で取り出すSQLを書け。
① 全行数(別名 全件)② price が入力済みの件数(別名 価格あり)③ category が入力済みの件数(別名 分類あり)④ stock が入力済みの件数(別名 在庫あり)
コーディング★★★無料
期待される結果

4列1行。7 / 6 / 6 / 6

ヒント

COUNT(*) と COUNT(列名) を使い分ける。列名を指定するとNULLが除かれる。

模範解答
SELECT
  COUNT(*) AS 全件,
  COUNT(price) AS 価格あり,
  COUNT(category) AS 分類あり,
  COUNT(stock) AS 在庫あり
FROM products;
解説

データの欠損状況を一目で把握するクエリ。実務でテーブルを受け取ったら、まずこれを流して「どの列がどれくらい埋まっているか」を確認する。

5仕上げ課題

SQL05-FINAL 【商品マスタの品質レポート】データ管理の担当者から「商品マスタの状態を一覧にしてほしい」と依頼された。欠損があっても分かりやすく表示すること。

表示する列
name → 別名「商品名」
② category(NULLなら「未分類」)→ 別名「分類」
③ price(NULLなら 0)→ 別名「単価」
④ stock(NULLなら 0)→ 別名「在庫」
⑤ 在庫金額(NULLを0として扱った price × stock)→ 別名「在庫金額」

並び順:在庫金額の大きい順
絞り込み:なし(全7件を表示)

期待される結果(5列 × 7行)
商品名 | 分類 | 単価 | 在庫 | 在庫金額
ノートPC | PC | 128000 | 5 | 640000
モニター | PC | 45000 | 7 | 315000
USBメモリ | 周辺機器 | 1500 | 120 | 180000
キーボード | 周辺機器 | 8500 | 18 | 153000
マウス | 周辺機器 | 3200 | 42 | 134400
新商品A | 未分類 | 25000 | 0 | 0
サンプル品 | 周辺機器 | 0 | 3 | 0
期待される結果

5列 × 7行が完全一致

ヒント

COALESCE を4箇所で使う(分類・単価・在庫・在庫金額の計算の中)。在庫金額は COALESCE(price,0) * COALESCE(stock,0)。並べ替えは別名で指定できる。

模範解答
SELECT
  name AS 商品名,
  COALESCE(category, '未分類') AS 分類,
  COALESCE(price, 0) AS 単価,
  COALESCE(stock, 0) AS 在庫,
  COALESCE(price, 0) * COALESCE(stock, 0) AS 在庫金額
FROM products
ORDER BY 在庫金額 DESC;
解説

NULLを含むデータを、欠損が分かる形で扱えた。「未分類」「0」と表示されることで、データが無いことが読む人に伝わる——これがNULLをそのまま出すのとの決定的な違いだ。

そして最後の2行に注目してほしい。新商品Aは単価25000円なのに在庫金額が0、サンプル品は在庫3個なのに0。どちらか片方が欠損していれば、掛け算の結果は意味を持たない。COALESCE で0にしたことで「計算できない」ことが数字として表れている。

もし COALESCE を書かなければ、この2行の在庫金額はNULLになり、並べ替えの位置も変わる。NULLは「見えない」からこそ、意識して扱わなければ結果が静かに狂う。SQLで最も多くの人がつまずくのがこの落とし穴で、集計値が合わないときの容疑者リストの筆頭になる。

次章では集計関数を学ぶ。SUMAVG がNULLをどう扱うか——ここでの知識がそのまま効いてくる。