【SQL】not in などでNULLまで抜け落ちる理由を言葉で考える
ご存知の方にとっては常識かもしれませんが、SQLではnot in
で条件を指定すると、NULLのレコードも一緒に抜け落ちてしまいます。
実はこの理由がよく分かっていなかったのですが、コードを言葉に置き換えて考えたら納得できたのでメモします。
SQLは<>やnot inでNULLも除かれてしまう
例えば次のような、生徒名と出身都市名のテーブルHometown
があったとします。
student | city |
---|---|
Ken | Tokyo |
Yui | Fukuoka |
Ayaka | Tsukuba |
Koki | NULL |
Mugi | Sendai |
このテーブルで「Fukuoka, Sendai以外の都市出身の生徒を抽出したい」場合、クエリはこんな感じに書けます。
select student , city from Hometown where city not in ('Fukuoka', 'Sendai')
しかしこの答えからは、Fukuoka, Sendai出身の生徒以外に、出身地がNULL
の生徒まで除去されてしまいます。
student | city |
---|---|
Ken | Tokyo |
Ayaka | Tsukuba |
対応策はnot exists ~
を使うことみたいです。詳細は、他の記事に譲りたいと思います。
では、なぜNULL
のレコードが抽出されなかったのでしょうか。
除かれる理由は「分からない」から
先ほどの例だとFukuoka, Sendai以外のcity出身者はTrue
となる条件ですが、残念ながらNULL
のレコードも抽出されませんでした。
-- 元のコード NULL not in ('Fukuoka', 'Sendai') -- -> False
ここで、NULL
は「分からない」値ということを思い出します。
値は「分からない」なので、そこに入るのは、もしかしたらFukuokaかもしれないし、もしかしたらTokyoかもしれないです。
ここで言えるのは、値が「分からない」がゆえにTrueかFalseか断定できない、つまりどちらでもないという事です。
どちらでもないので、in
の条件にもnot in
にも当てはまりません。
これが、NULL
がin
にもnot in
にも含まれない理由だと理解しました。
参考
考え方は以下の本に載っていました。