SQLのNULL比較方法についてまとめています。
SQLでNULLの比較をするには、WHERE句で通常の値と同じように条件指定するのではなくIS NULLやIS NOT NULLなどのNULL比較専用の演算子を使う必要があるんですね。


NULL比較はIS NULL演算子を使う
IS NULL演算子は、対象カラムがNULLのレコードのみ対象とするための特殊な演算子です。NULLは特殊な扱いなので=NULLという記述だと正しく意図した動きをしてくれません。
以下は、titlesテーブルの「to_date」カラムにNULLを設定したレコードを挿入し、IS NULLを使ってselectした例です。
- mysql> desc titles;
- +-----------+-------------+------+-----+---------+-------+
- | Field | Type | Null | Key | Default | Extra |
- +-----------+-------------+------+-----+---------+-------+
- | emp_no | int | NO | PRI | NULL | |
- | title | varchar(50) | NO | PRI | NULL | |
- | from_date | date | NO | PRI | NULL | |
- | to_date | date | YES | | NULL | |
- +-----------+-------------+------+-----+---------+-------+
- 4 rows in set (0.00 sec)
- mysql> INSERT INTO `titles`(`emp_no`, `title`, `from_date`, `to_date`) VALUES (10001, 'Staff', '1992-04-01', NULL);
- Query OK, 1 row affected (0.00 sec)
- select * from titles where to_date IS NULL;
- +--------+-------+------------+---------+
- | emp_no | title | from_date | to_date |
- +--------+-------+------------+---------+
- | 10001 | Staff | 1992-04-01 | NULL |
- +--------+-------+------------+---------+
- 1 row in set (0.15 sec)
【関連記事】
▶MySQLのNULL判定はどうやる? 除外判定やNULLのSUMを取得するには?
ストアドファンクション内でもIS NULL演算子が使えます。
- SET GLOBAL log_bin_trust_function_creators = 1;
- DELIMITER //
- CREATE FUNCTION CheckNULL(name varchar(30))
- RETURNS VARCHAR(20)
- BEGIN
- declare msg varchar(20);
- declare depname varchar(20);
- select dept_name into depname from departments where dept_no=num;
- if depname IS NULL then set msg = 'NULL';
- else set msg=depname;
- END IF;
- return msg;
- END
- //
- DELIMITER ;
【関連記事】
▶ SQLのif文でNULL判定するサンプルコード
1行目のSET GLOBAL log_bin_trust_function_creators = 1は、エラー回避用に設定しています。1行目の設定をしないと、以下のエラーが出力されます。
- ERROR 1418 (HY000): This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you *might* want to use the less safe log_bin_trust_function_creators variable)
デフォルトでは、CREATE FUNCTION ステートメントを実行するためにDETERMINISTIC、NO SQL、または READS SQL DATA の少なくとも 1 つを明示的に指定する必要があるんですね。
参考)MySQL :: MySQL 5.6 リファレンスマニュアル :: 20.7 ストアドプログラムのバイナリロギング
NOT INでNULLは使えない、AND演算子でIS NOT NULL条件を追加
NOT INにNULLを含めると「どんなデータにもマッチしない」という条件になってしまいます。例えば、Sales、Development、NULL以外という条件を指定するには、NOT IN ( ‘Sales’, ‘Development’ )
AND dept_name IS NOT NULLのように記述します。
- SELECT *
- FROM `departments`
- WHERE dept_name NOT IN ( 'Sales', 'Development', NULL );
- Empty set (0.00 sec)
- SELECT *
- FROM `departments`
- WHERE dept_name NOT IN ( 'Sales', 'Development' )
- AND dept_name IS NOT NULL;
- +---------+--------------------+
- | dept_no | dept_name |
- +---------+--------------------+
- | d009 | Customer Service |
- | d002 | Finance |
- | d003 | Human Resources |
- | d001 | Marketing |
- | d004 | Production |
- | d006 | Quality Management |
- | d008 | Research |
- +---------+--------------------+
- 7 rows in set (0.00 sec)
【関連記事】
▶SQL not in データの除外指定 NULLや複数カラムを扱う方法
まとめ

- NULL判定をするにはIS NULL演算子を使う
- ストアドファンクション内でもIS NULLを使ってNULL比較が可能
- NOT INでNULLを含めるには、AND演算子でIS NOT NULLを使う