みどりのジーパン

Data Science / Data Engineering / MLOpsを勉強中

【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 ~を使うことみたいです。詳細は、他の記事に譲りたいと思います。

sql55.com

では、なぜNULLのレコードが抽出されなかったのでしょうか。

除かれる理由は「分からない」から

先ほどの例だとFukuoka, Sendai以外のcity出身者はTrueとなる条件ですが、残念ながらNULLのレコードも抽出されませんでした。

-- 元のコード

NULL not in ('Fukuoka', 'Sendai') -- -> False

ここで、NULLは「分からない」値ということを思い出します。

値は「分からない」なので、そこに入るのは、もしかしたらFukuokaかもしれないし、もしかしたらTokyoかもしれないです。 ここで言えるのは、値が「分からない」がゆえにTrueかFalseか断定できない、つまりどちらでもないという事です。 どちらでもないので、inの条件にもnot inにも当てはまりません。 これが、NULLinにもnot inにも含まれない理由だと理解しました。

参考

考え方は以下の本に載っていました。

www.oreilly.co.jp