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はまだ不明ってことだから、もしかしたら更新されて出るかもしれないらしーよ

 

(おしまい)

 

※当記事はアフロの個人的な見解を含みます

 

 

 

結びのメッセージ

HOMEGROWINロゴ背景

Switch with us!

採用エントリー

ご応募はこちら