[SQL] 論理演算子とNULLの挙動まとめ
前提
この記事の内容はJISX3005-2で裏をとっているつもりですが、間違いがあればご指摘ください。記載したSQLはほとんどのデータベースで同じ結果になると思いますが、挙動の確認はBigQueryで行っています。
導入
突然ですがクイズです!全問正解できますか?
Q1
以下のSQL文が返すのは TRUE
FALSE
NULL
のどれでしょう?
SELECT
TRUE OR NULL AS col1,
FALSE AND NULL AS col2,
NULL AND FALSE AS col3
;
正解はcol1から順に TRUE
FALSE
FALSE
です。 NULL
と間違えた人もいるのでは?
Q2
次の問題です。以下のSQLが返すのは TRUE
FALSE
NULL
のどれでしょう?
SELECT NULL OR FALSE;
正解は NULL
です。おそらく FALSE
と迷う人もいたでしょう。
解説
Q1を誤って NULL
と答える心理はおそらくこうです。数値演算などにNULLが含まれるとNULLが返る[1]から、論理値の演算も同様だと思い込んでいませんか?
SELECT 1 + CAST(NULL AS INT64); -- NULL
Q2で FALSE
と間違った人は、左辺 NULL
がfalsyだから(短絡評価できず)右辺の FALSE
が評価されて返ってくると思ったのではないでしょうか?例えばPythonでは None or False
は False
なのでその考えは正しいですが、SQLではさにあらずです。
# python
None or False # False
False or None # None
結論、論理演算子の挙動を表にまとめると以下の通りです。 AND
OR
については左辺・右辺の順番によらず、結果は同じです。
(AND) | TRUE | FALSE | NULL |
---|---|---|---|
TRUE | TRUE | FALSE | NULL |
FALSE | FALSE | FALSE | |
NULL | NULL |
(OR) | TRUE | FALSE | NULL |
---|---|---|---|
TRUE | TRUE | TRUE | TRUE |
FALSE | FALSE | NULL | |
NULL | NULL |
(NOT) | |
---|---|
TRUE | FALSE |
FALSE | TRUE |
NULL | NULL |
「上記の挙動はこういう思想にもとづくからこう覚えるとよい」と説明できればよいのですが、JISX3005-2にも表としてまとまっているだけなので思想を読み取るのが難しいです。こじつけで覚えるなら「TRUE
> NULL
> FALSE
のように順序が決まっていて、 AND
は両辺を比較して順序が後のものを返す( OR
は先のものを返す)」[2]などと覚えることができます。
所感
ややこしいから COALESCE()
とか使って NULL
を避けるのが一番よいのでは?という気もします。それと、以下について説明できる方がいたらぜひ教えてください。
「上記の挙動はこういう思想にもとづくからこう覚えるとよい」と説明できればよいのですが
Discussion