🎃

Q. なぜ SQL では NULL 判定に IS 演算子を使うの?

2024/07/18に公開

気になったので調べた。
あいまいな解釈が含まれるので、ご指摘ありましたらぜひください。

Java, JavaScript など一部の言語では、ある値と null が比較されたとき、false を返すのが一般的とされています。これは、nullFalsy な値 だとされているからです(参考)。
この考え方がベースになっていたので、「SQL ってなんでわざわざ null 判定に専用の演算子があるんだ?」と思っていました。

= で比較するとどうなる?

SQL では、値の比較は = 演算子で行うのが通例です。
では、null との比較に = を使うとどうなるのでしょうか?

一例として、Oracle Database のドキュメントでは、値としては null、評価としては unknown が返されると書かれています。

https://docs.oracle.com/cd/E82638_01/sqlrf/Nulls.html

unknown?聞きなれないワードが出てきました。
どうやら、私たちが知っているような論理評価の方法とはすこし違うみたい。

SQL の論理モデル

一般的なプログラミング言語では、2値論理を採用しています。これは、条件式の結果を true または false のどちらかに限定する考え方です。
これに対し、SQL では 3値論理 という考え方が採用されています。これは、先ほどの true falseunknown を追加した論理モデルになります。

null

ここで少し脱線します。

そもそも、null とはなんでしょうか?なんとなく「からっぽの値」「未定義」みたいなイメージを持っていましたが、調べた感じは次の二つに分解できます。

  • 未知: まだ判明していない情報。(例:空中で回転するコインの裏表)
  • 適用不能: オブジェクトが持てない情報。(例:コインの目の色)

null とは、あくまで上2つを示す 記号 であると解釈するのがよさそうです。

unknown

さて、本題に戻ります。

3値論理において unknown は、「判定が不可能なこと」を示す値です。
false が「偽、否定」を示すのに対し、unknown は「判定不能」を示します。やや似た概念(というか今まで同義として扱ってきた)なので、すごく混乱します。

そして、この論理値は前述のとおり null との比較演算などでよく現れます。

なぜ unknown は必要なのか?

なぜ unknown は必要なのでしょうか?
通常のプログラミング言語と同じ false で代用することの何が問題なのでしょう?

ここからは自分なりの解釈になるのですが、null はあくまで「記号」でしかないと考えます。
ほかの値が「紙に書かれたデータ」だとすると、null は「紙すら存在しない」もしくは「紙を置く空間すらない」ことを示す値です。これは上で示した「未知」「適用不能」に該当します。

SQL 上では、文字列数字真偽値などの様々な「値」と、null という「記号」を明確に分離することを目的として unknown が用いられる、と考えます。

一例として、コインの裏表を truefalse で考えてみます。まだ空中で回転しているコインは null とします。
このとき、図らずとも「コインが裏の状態(false)」と「コインの裏表が確定していない状態(null)」が同じだと判定されてしまいます。これは困った。
こういった「複数の意味をひとつの単語に対して課すこと」は、わたしたちの意図しない場所で思いもよらない論理エラーを引き起こす可能性があります。これを防ぐために3値論理が存在し、安全性を担保しているのではないか?と結論付けます。

これらを踏まえたうえで、あえて「この値は 未知/適用不能 な状態か?」という状態を検査する場合を考慮して IS 演算子が用意されているのではないか?と思っています。

参照

https://codezine.jp/article/detail/532

Progate Path コミュニティ

Discussion