突然ですが、
SELECT * FROM テーブル名 WHERE 1=1;
とSQLを実行するとどうなると思いますか?
1 = 1 が検索条件に指定されていますが、1 = 1 はtrueなので全件検索(早い話が条件がないのと一緒)全レコードが抽出されます。
では、以下はどうでしょうか?
SELECT * FROM テーブル名 WHERE NULL= NULL;
一見、NULL=NULLはあってそうなので、データは抽出されそうですが、リレーショナルデータベースの世界では抽出されません。
NULLを検索条件にするには IS NULLが必要になります。
なぜこんな仕様なんでしょうか?
それはリレーショナルデータベースの世界に導入された3値論理が影響(悪さ?)しています。
3値論理というのは、trueとfalseの組み合わせからなる2値論理に、unknownを加えたものです。
ひとまず、2値論理の真理値表からおさらいしてみましょう。
###2値論理
AND | TRUE | FALSE |
---|---|---|
TRUE | true | false |
FALSE | false | false |
ANDは、どちらもtrueの場合にのみ、trueになるパターンですね。
OR | TRUE | FALSE |
---|---|---|
TRUE | true | true |
FALSE | true | false |
ORはどちらかがTRUEの場合、trueになります。
では3値論理の真理値表はどうでしょうか?
###3値論理
AND | TRUE | FALSE | UNKNOWN |
---|---|---|---|
TRUE | true | false | unknown |
FALSE | false | false | false |
UNKNOWN | unknown | false | unknown |
OR | TRUE | FALSE | UNKNOWN |
---|---|---|---|
TRUE | true | true | unknown |
FALSE | true | false | unknown |
UNKNOWN | true | unknown | unknown |
マトリックスでtrueになっている組み合わせしかデータは抽出されません。
一見、分かるような、よく分からないような。
少し話が脱線したので、IS NULLと書かないといけない理由に話を戻してと。
プログラミング言語が=null というような書き方を許容しているのが多くあるのに、SQLはIS NULLなんて書かないといけないのでしょうか?
それはSQL標準規格 で定められているから なのですが、その理由を少し想像してみたいと思います。
(※ここから先は、はっきりと書かれている文献等を見たわけではないので、私の想像が入っています。あくまで参考程度にしてください)
リレーショナルデータベースを提唱したコッドさんは、3値論理を飛び越えて、4値論理を提唱していたそうです。
え!?4値?もう一個はなに?
というと、NULLには2種類あると考えていたそうです。
4値論理の2種類のNULL
・値がわからない NULL
例えば、従業員マスタに性別 という列があると仮定しましょう。
従業員マスタ
従業員コード | 名前 | 性別 |
---|---|---|
1 | テスト1 | 男性 |
2 | テスト2 | NULL |
テスト2さんの性別がNULLの場合は、男性か女性か分からないという状態ですね。
こういう意味のNULLは値がわからない を表しています。
・ありえない状態のNULL
入学テーブル
受験者コード | 不合格日 |
---|---|
1 | NULL |
2 | NULL |
テーブル設計ミスだろ!とは思うのですが、この状態のNULLのいい例が思いつかなかったのです。
入学した人に不合格 はありえませんね(特殊なパターンはあるかもしれませんが)
ありえない状態のNULL とは、意味的に存在しない状態を指しています。
コッドさんは、RDBの世界にも4値論理を入れて、NULLも2種類で表現したかったそうなのですが、大変になりそうってことで実装されなかった・・・
IS NULLも間違えやすいのに、そのNULLが2種類になんてしまったら、、、末恐ろしい。
こんな風にNULLには2種類の意味が込められた単純な値ではない
ということを表すために、IS NULL が導入されたのでしょう・・・たぶん、知らんけど。
とにかく、NULLというのはバグの原因になったり、なんで数が合わないんだー!とか色々悪さをしてくれます。
(理論で考えたら納得できるのですが、バグを生んだり悩んだりするときって疲れてて正常な判断できないんですよね~。)
そういうわけで、これから私がデータベースからなぜNULLを排除すべきと考えているか?
非正規化すべきではないと考えているのか、もう一度自分の中でほりさげる意味で
理由を書いていきたいと思います。