SQLでNULL検索

f:id:pigggg:20220204141650p:plain

NULLの値も取れるだろうと思っていたが取れなかったのでメモ

mysql> select * from hoge;
+------+---------------------+-------+---------+
| memo | id                  | title | subject |
+------+---------------------+-------+---------+
| A    |  642095173214856378 | test  | test    |
| NULL |  642095173214856379 | test  | test    |
| B    | 2594777263822576559 | test  | hoge    |
+------+---------------------+-------+---------+

このような内容のテーブルがあったとして、memo <> 'A' のデータを取ろうとする
単純に where memo <> 'A' とすると自分として memo = NULL, B が取れるものだと思っていました。

実際はこう

mysql> select * from hoge where memo <> 'A';
+------+---------------------+-------+---------+
| memo | id                  | title | subject |
+------+---------------------+-------+---------+
| B    | 2594777263822576559 | test  | hoge    |
+------+---------------------+-------+---------+
1 row in set (0.00 sec)

memo = B しか取れていない…

memo not in ('A') にしても結果は同じ

mysql> select * from hoge where memo not in ('A');
+------+---------------------+-------+---------+
| memo | id                  | title | subject |
+------+---------------------+-------+---------+
| B    | 2594777263822576559 | test  | hoge    |
+------+---------------------+-------+---------+
1 row in set (0.01 sec)

なぜかと言うと、
DBではnullとそれ以外の値で区別されていると同時に、検索対象としては特殊な扱いを受けるように設計されているから
らしい

参照元 style.potepan.com なるほどなぁ…

なので null まで取りたいとなったらこう書くことになる。

mysql> select * from hoge where memo not in ('A') or memo is null;
+------+---------------------+-------+---------+
| memo | id                  | title | subject |
+------+---------------------+-------+---------+
| NULL |  642095173214856379 | test  | test    |
| B    | 2594777263822576559 | test  | hoge    |
+------+---------------------+-------+---------+
2 rows in set (0.02 sec)