SQLにおけるNULLの扱い
表には必ずデータを入れなくてはならない訳ではありません。値を入れなくても良い列には、値が入っていなくても問題はありません。このように表の中に値が存在していないことを「NULL」(ヌル)といいます。
NULLは何も入っていない状態を表します。そのため、数値型の列に「0」が入っている状態や、文字列型の列にスペース、タブなどの「空白」が入っている状態とは異なります。NULLは本当に何も入っていないことを表します。
実際に問合せを行うと、ORACLEのSQL*PLUSでは何も表示されず、MS-SQLのクエリアナライザでは「NULL」という文字が返されます。
ここでは、次のような「社員名簿」表を使って解説します。
社員番号 | 名前 | 出身地 | 年齢 |
1 | 山田太郎 | 東京都 | 28 |
2 | 佐藤花子 | □(半角スペース) | |
3 | 鈴木史郎 | 25 | |
4 | 斉藤美穂 | 24 |
この表には「出身地」列と「年齢」列に空白があります。この空白は、佐藤花子さんの「出身地」列は半角スペースで空白にしてありますが、その他の空白はすべてNULLが指定されています。
このNULLが値として入力されている表に対して、すべての列を返すように問合せると、次のようになります。
SQL文
SELECT * FROM 社員名簿;
実行結果
社員番号 | 名前 | 出身地 | 年齢 |
1 | 山田太郎 | 東京都 | 28 |
2 | 佐藤花子 | ||
3 | 鈴木史郎 | 25 | |
4 | 斉藤美穂 | 24 |
SQL文
SELECT * FROM 社員名簿;
実行結果
社員番号 | 名前 | 出身地 | 年齢 |
1 | 山田太郎 | 東京都 | 28 |
2 | 佐藤花子 | NULL | |
3 | 鈴木史郎 | NULL | 25 |
4 | 斉藤美穂 | NULL | 24 |
ORACLEのSQL*PLUSでは、NULLも半角スペースの部分もすべて空白で返され、MS-SQLクエリアナライザでは、半角スペースは空白で、NULLのところには「NULL」と入って返されています。
NULLの入力
INSERT INTO 社員名簿 VALUES ( 5, '小泉純一郎', '神奈川県', NULL)
SELECT * FROM 社員名簿;
実行結果
社員番号 | 名前 | 出身地 | 年齢 |
1 | 山田太郎 | 東京都 | 28 |
2 | 佐藤花子 | NULL | |
3 | 鈴木史郎 | NULL | 25 |
4 | 斉藤美穂 | NULL | 24 |
5 | 小泉純一郎 | 神奈川県 |
INSERT INTO 名簿 VALUES ( 6, '竹下登', '', 23 );
IS NULL演算子
ここまでNULLやデータが空という意味が理解できたと思います。ただ、ORACLEなどでは、空白で出力された場合、NULLなのか空白文字が入っているのか区別がつきません。その場合に、NULLの認識に使うのがIS NULL演算子です。
先ほど5つ目の行を追加した「社員名簿」表でIS NULL演算子を使って問合せを行うと次のようになります。
SELECT * FROM 社員名簿 WHERE 年齢 IS NULL;
実行結果
社員番号 | 名前 | 出身地 | 年齢 |
2 | 佐藤花子 | ||
5 | 小泉純一郎 | 神奈川県 |
WHERE句の指定で、「年齢」列がNULLの行だけを取得することができます。IS NULLの記述が数値型、文字列型のどちらにも同じように使うことができます。
また IS NULL演算子はNOT演算子と組合せて使うこともできます。このときの検索はNULLが入っていない行のデータを検索することになります。
SQLは英語の表記に基づいているので「NOT IS NULL」ではなくて、「IS NOT NULL」となります。次のように問合せると、「年齢」列のNULLが値にない行を出力することができます。
SELECT * FROM 社員名簿 WHERE 年齢 IS NOT NULL;
実行結果
社員番号 | 名前 | 出身地 | 年齢 |
1 | 山田太郎 | 東京都 | 28 |
3 | 鈴木史郎 | 25 | |
4 | 斉藤美穂 | 24 |
社員名簿
社員番号 | 名前 | 出身地 | 年齢 |
1 | 山田太郎 | 東京都 | 28 |
2 | 佐藤花子 | ||
3 | 鈴木史郎 | 25 | |
4 | 斉藤美穂 | 24 |
SELECT * FROM 社員名簿 WHERE 年齢 = NULL;
レコードが選択されませんでした。
ここでは、比較演算子の=演算子を使って、年齢がNULLの行を判断しようとしています。しかし、実際にはNULLが入っている行(レコード)があるのに、「レコードが選択されませんでした」という結果が出ています。NULLかどうかには、IS NULL演算子を使わないと判断ができないのです。