PHP
MySQL

NOT EXIST (SELECT…) を NOT IN (リテラルリスト) で置き換える事について

More than 1 year has passed since last update.

結果としては危険です

IN句の値リストにNULLが入ると結果がUNKNOWNになるためです。

データ数も少なくSQLも読みやすくなるのでいいかも~♪てか思った。
事前に関数で否定値集合リストを取得し値リストでSQLのNOT INに入れる。良いんじゃないかと調べたら結構なデメリットがありました。
否定値集合リストが無い場合、関数の返却値でNULLとする場合の動作が怖いです。
当初 NOT IN (NULL) で無効化されると想定したのですが、そうではありませんでした。

検証します。

返却が不正
mysql> select 1 in (null);
+-------------+
| 1 in (null) |
+-------------+
|        NULL |
+-------------+
1 row in set (0.00 sec)

mysql> SELECT 1,2,3 FROM dual WHERE 1 NOT IN (4,5,6);
+---+---+---+
| 1 | 2 | 3 |
+---+---+---+
| 1 | 2 | 3 |
+---+---+---+
1 row in set (0.00 sec)

mysql> SELECT 1,2,3 FROM dual WHERE 1 NOT IN (null);
Empty set (0.00 sec)

mysql>

PHP内でリテラルリストのNULL判定条件分岐を入れ忘れた場合の危険性を考えると使わない方が良さ気です。

ちょっとだけ考えた事

-- SQL -- 結果
SELECT 1 in (1,2,3,4,5,null); -- 1
SELECT 6 in (1,2,3,4,5,null); -- NULL
SELECT 6 in (1,2,3,4,5); -- 0
SELECT 1 AND 1; -- 1
SELECT 0 AND 1; -- 0
SELECT 0 AND 0; -- 0
SELECT NULL AND 1; -- NULL
SELECT NULL AND 0; -- 0
SELECT NULL AND 0; -- 0
SELECT NULL AND NULL; -- NULL
SELECT NULL IS NULL AND NULL IS NULL; -- 1
SELECT NULL IS NULL AND 1 IS NOT NULL; -- 1
SELECT NOT NULL; -- NULL
SELECT NOT NULL AND NOT NULL; -- NULL
SELECT NOT NULL OR NOT NULL; -- NULL
SELECT NOT NULL OR 1; -- 1
SELECT NOT NULL OR 0; -- NULL
SELECT NOT NULL AND 1; -- NULL
SELECT NOT NULL AND 0; -- 0
mysql> SELECT 1, (select 1 from dual where 1 in (null)), (select 1 from dual where 1 in (null)) IS NULL;
+---+-------+-------+
| 1 |       |       |  省略しました
+---+-------+-------+
| 1 |  NULL |     1 |
+---+-------+-------+
1 row in set (0.00 sec)

もうヤケクソでコード叩きましたです。酷いもんです。
結果セットを積み上げて、TRUE > NULL > FALSE こんな優先順位で返却してるのかと思ったけど違うようです。
ロジック理解が面倒くさいので、こんなもんなんだと思うようにしました(諦めた)
スパッと論旨明快で簡潔に理解出来る方法ないものですかね…
参考リンクの4番目に解となるリンクを載せておきます。疑問に思った方は読むと面白いです。
同僚に教えていただけました。ありがとうございます!おかわりください!
ただし、個人的に、納得は、したくない。

参考リンク

どれも面白いです。是非読んで下さい。

  1. MySQL の IN 句における NULL の扱いについて - しがないエンジニアの技術メモ http://d.hatena.ne.jp/harapeko_san/20111130/1322623529
  2. EXISTS - オラクル・Oracleをマスターするための基本と仕組み http://www.shift-the-oracle.com/sql/exists-condition.html
  3. NULL の特性 - オラクル・Oracleをマスターするための基本と仕組み http://www.shift-the-oracle.com/element/null/nulls-effect.html
  4. 3値論理とNULL (1/3):CodeZine http://codezine.jp/article/detail/532