1. NULLは値ではない。
NULLは未知
または適用不能
を意味する。値ではなく、そこに値が存在しないことを示す記号である。
2. 述語をまともに適用できず、適用するとunknown
が生じ、SQLが直感に反する動作をする。
NULLに比較述語を適用した結果、常にunknown
となる。
単純な例として、
SELECT * FROM tbl WHERE col = NULL;
これは、NULLの行を選択することはできない。
何故ならば、col = NULL
とするとこの評価値はunknown
となる。クエリの結果として選択されるのは評価値がtrue
の行のみである。
以下が正しい。
SELECT * FROM tbl WHERE col IS NULL;
3. 第3の真理値unknown
SQLの世界には第3の真理値であるunknown
が存在する。
true,false,unknownの間に次のような優先順位があると考えるとわかりやすい。
- ANDの場合: false > unknown > true
- ORの場合: true > unknown > false
問題を引き起こすSQLの例
排中律が成立しない
SELECT * FROM students WHERE age = 20 OR age <> 20;
このSQLはageがNULLのレコードを選択しない。
CASE式
CASE col_1
WHEN 1 THEN 'o'
WHEN NULL THEN 'x'
END
この式は絶対にx
を返さない。2つ目のWHEN句がcol_1 = NULL
の省略形であるため。
対策
テーブルにNOT NULL成約をつけて極力NULLを排除し、以下の指針を検討する。
- コード値の場合、未コード化用コードを割り振る
- 名前の場合、「名無し」を割り振る
- 数値の場合、0で代替する
- 日付の場合、最大値、最小値で代替する