BLOG

2024-07-24 テクニカル

なぜSQLでは=NULLではなく is NULLなのか?

ある日のアフロ家

アフロ:うーん・・・、レコードが取れないな

息子氏:パパ、どうしたの?

アフロ:うん、会社の社員テーブルからボーナスがNULLの人を取りたいんだけど、誰も取れないんだ。こんな感じで。

 

select 氏名, ボーナス from 社員 where ボーナス=NULL;

 

息子氏:ダメだよ、パパ。SQLではNULLかどうかを見たいときは is NULL って書くらしーよ。
だから、こんな感じで書けば取れるらしーよ

select 氏名, ボーナス from 社員 where ボーナス is NULL;

 

アフロ:そうだったのか~ でもなんでNULLの場合は=が使えないんだ??
Javaで変数と比較するときはボーナス==1000 とか ボーナス==null で同じ書き方できるのに??

 

息子氏:Javaとかのプログラミング言語は真と偽の2値論理だけど、SQLは「不明」を加えた3値論理だから、らしーよ

アフロ:3値論理???

息子氏:あともし=NULLで取れるようになると、それはそれで困るらしーよ

 

3値論理とは?

アフロ:で、3値論理ってなんなのよ??

息子氏:2値論理は真と偽のどちらか、ていうわかりやすい考えでJavaはこれを使ってるらしーよ。
それに対してSQLで使われてる3値理論っていうのは、真と偽だけじゃなく「不明」ていう概念があって、NULLは「不明」ってこと。

だからボーナス=NULLっていう条件はそもそも等しいかわからないから「不明」って考えるらしーよ

 

もし=NULLで検索できるとどうなる?

 
アフロ:なるほど・・・ でもボーナスがNULLで登録されているわけだから、ボーナス=NULLで取れてもいいんじゃないか??
なんで is NULL っていう別の書き方を使わないといけないんだい??
 
息子氏:確かに使い分けないといけないから最初は間違えるよね。
でももしボーナス=NULLでレコードが取れるようになるってことは、NULL=NULLが真になるわけで、そうなると結合したSQLで取れるデータも変わってくるらしーよ
 
例えばこんな2つのテーブルがあって、社員名とボーナスのデータがあるとするでしょ
 
■アプリグループ社員テーブル
社員名 ボーナス
マリオ 10000
ルイージ 20000
クッパ NULL
 
■モバイルグループ社員テーブル
社員名 ボーナス
ノコノコ 10000
クリボー 20000
ドッスン NULL
 
 
でアプリグループとモバイルグループでボーナスが同じ金額の社員を調べよう!とするじゃない?
 
SELECT アプリグループ社員.社員名, モバイルグループ社員.社員名, アプリグループ社員.ボーナス FROM アプリグループ社員 INNER JOIN モバイルグループ社員 ON アプリグループ社員.ボーナス = モバイルグループ社員.ボーナス
 
を実行すると、
 
マリオ ノコノコ 10000
 
が取れて、これが欲しい結果だよね
 
これがもしNULL=NULLが真で成立するとしたら、ボーナスがNULLのメンバーも同じ金額ということになるから、
 
 
マリオ ノコノコ 10000
クッパ ドッスン NULL
 
 
ていう結果になるらしーよ
 
アフロ:NULL同士のデータも取れしまうのか、確かにクッパとドッスンのデータはいらないなあ
そしたらボーナス〈〉NULL の条件もつけたらいいんじゃないか??
 
息子氏:そうすると、NULLがあり得る列を条件にするとき、全部に〈〉NULLの条件もつけないといけなくなるらしーよ
 
アフロ:うーん、それは大変だなあ
 
息子氏:そんなわけで、結合があるSQLではNULL=NULLは成立しない方がいいから、is NULLがあった方がいいらしーよ
 
アフロ:そうかー、じゃあちゃんとis NULLを使ってうちの会社でボーナスがNULLの社員を検索しなおすかー
 
SELECT 社員名, ボーナス FROM 社員 WHERE ボーナス is NULL;
 
アフロ NULL
 
 
 
おー、ちゃんと取れたな。わしのボーナスがNULLっと…
 
息子氏:でもNULLはまだ不明ってことだから、もしかしたら更新されて出るかもしれないらしーよ
 
 
(おしまい)
 
※当記事はアフロの個人的な見解を含みます

 

 

 

The following two tabs change content below.

アフロ・ナミヘイ

PostgreSQL推進委員長。アンチOracle派筆頭。 標準SQLに反する書式は許しません。 (+)とか使ってると激おこ。 アフロは天然。