厄介なNULL| プログラミングの砂場

プログラミング学習やタイピング練習に役立つツールを公開しているサイトです。

厄介なNULL

「NULL」とは列に設定する値が未定の時に時折使用される印(マーカー)です。

「NULL」に対しては比較演算子などが使用できないので注意が必要です。

目次

1. はじめに

ここでは、商品テーブル(Shouhin)を使ってNULLの取り扱いを見てみましょう。

まずは、Shouhinの内容を下のSQLでデータを確認してください。

SELECT
    *
FROM
    Shouhin
WHERE
    shouhin_id=26
OR
    shouhin_id=27
shouhin_id name name_kana category_id price
26 セット商品 せっとしょうひん 4000
27 セット商品2 せっとしょうひん2 3000

セット商品を2種類売り出そうとShouhinテーブルに登録しましたが、商品カテゴリが決まっていないため、とりあえず商品カテゴリに「NULL」を設定してある状態です。

この2商品のcategory_idと「NULL」が入っていますが、目には見えません。(ピンクの部分)

この「NULL」入りデータに対して比較演算子を使ってみます。

2. NULLに対しての比較演算子

category_idが1は野菜、2は果物です。

野菜でも果物でもない商品を下のSQLで取得してみます。

SELECT
    *
FROM
    Shouhin
WHERE
    category_id <> 1 AND category_id <> 2
shouhin_id name name_kana category_id price

セット商品とセット商品2は、野菜でも果物でもないはずなのに、なにも取得できませんでした。

では、これはどうでしょう?

category_idがNULLと等しいものを取得しようとしています。

SELECT
    *
FROM
    Shouhin
WHERE
    category_id = NULL
shouhin_id name name_kana category_id price

こちらも上と同じく、なにも取得できませんでした。

これは、「NULL」に対しては、比較演算子が無効なことを意味します。

「NULL」に対しては比較演算子が使えないことがわかりました。

では、「NULL」のデータを捕まえるにはどのようにしたらいいでしょう?

3. IS NULLとIS NOT NULL

「IS NULL」と「IS NOT NULL」を使うと「NULL」を捕まえることができます。

3-1. IS NULL

「商品カテゴリがNULL」という条件を指定するには下のようにします。

SELECT
    *
FROM
    Shouhin
WHERE
    category_id IS NULL
shouhin_id name name_kana category_id price
26 セット商品 せっとしょうひん 4000
27 セット商品2 せっとしょうひん2 3000

これで、category_idがNULLの商品を取得できました。

3-2. IS NOT NULL

「NOT」を使って「商品カテゴリがNULLではない」という条件も指定できます。

SELECT
    *
FROM
    Shouhin
WHERE
    category_id IS NOT NULL
shouhin_id name name_kana category_id price
1 アスパラガス あすぱらがす 1 256
2 かぼちゃ かぼちゃ 1 300
3 キャベツ きゃべつ 1 128


category_idがNULLの商品は取得されていません。

4. NULLに対しての演算

ここでは、簡単のためSELECTのみで演算をしてみます。

単純に「1+10」の計算結果を表示するSQLです。

※実は、SELECTはFROMでテーブルを指定しなくても使えます。

SELECT 1+10
1+10
11

では、「NULL」に対して計算を施してみます。

SELECT NULL+10
1+10
 

計算結果は、「NULL」です。

「NULL」は「未定」なので、「未定+10」の答えも「未定(NULL)」となるわけです。

計算式の中に「NULL」が紛れ込んでいるとその答えは「NULL」になるので注意が必要です。

5. 集約関数でのNULLの取り扱われ方

Shouhinテーブルのpriceに「NULL」が紛れ込んでいた場合、集約関数の結果も「NULL」になるのでしょうか?

5-1. 合計値を求める

SELECT SUM( price ) FROM Shouhin

NULLは無視されて(無いものとして)合計値が計算される。

5-2. 最大値を求める

SELECT MAX( price ) FROM Shouhin

NULLは無視されて(無いものとして)最大値が取得される。

5-3. 最小値を求める

SELECT MIN( price ) FROM Shouhin

NULLは無視されて(無いものとして)最小値が取得される。

5-4. 平均値を求める

SELECT AVG( price ) FROM Shouhin

NULLは無視されて(無いものとして)平均値が計算される。

5-5. データ件数を求める

SELECT COUNT( price ) FROM Shouhin

priceがNULLの行はカウントされない。

テーブルの全行数を求めるつもりで「COUNT( price )」を使ってもpriceがNULLの行はカウントされないので注意が必要です。

確実に、テーブルの全行数を求めるには、「COUNT( * )」を使いましょう。

練習用テーブルのShouhinのpriceにはNULLがありません。

COUNTの動作を試す場合は、NULLが2件紛れ込んでいるcategory_idを使ってみてください。

SELECT COUNT( category_id ) FROM Shouhin

SELECT COUNT( * ) FROM Shouhin

2件の差があることが確認できます。

6. まとめ

「NULL」は「未定」を表す印(マーカー)です。

「NULL」に対しては、比較演算子が使えません。

「NULL」を捉えるには、「IS NULL」もしくは、「IS NOT NULL」を使用します。

また、「NULL」に対する演算の答えはいつも「NULL」になります。

「NULL」を許容しているテーブルについては、列に対しての条件指定や演算に注意が必要です。

集約関数SUM、MAX、MIN、AVGは、指定された列値のNULLを無視(無いものと)して計算した結果を返します。

集約関数COUNTは、指定された列値にNULLを持つ行を省いた行数を返します。

SQLを書く前に、テーブルのどの列がNULLを許容しているか確認しておくといいと思います。

ちなみに、練習用テーブルで、NULLを許容しているのは、Shouhinテーブルのcategory_id列のみです。


次は、「INとBETWEEN」についてです。


TOP