🌊

[SQL] 論理演算子とNULLの挙動まとめ

2023/07/15に公開

前提

この記事の内容は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 FalseFalse なのでその考えは正しいですが、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 を避けるのが一番よいのでは?という気もします。それと、以下について説明できる方がいたらぜひ教えてください。

「上記の挙動はこういう思想にもとづくからこう覚えるとよい」と説明できればよいのですが

脚注
  1. これは「<数値式>に単純に含まれるいずれかの<数一次子>の値がナル値ならば,<数値式>の結果は,ナル値とする。 」とJISX3005-2にも明記されています。 ↩︎

  2. この記事を書きながら適当に考えた覚え方なので、一般論かのように話すと恥をかく可能性があります。注意。 ↩︎

Discussion