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があり得る列を条件にするとき、全部に〈〉NULLの条件もつけないといけなくなるらしーよ
アフロ:うーん、それは大変だなあ
息子氏:そんなわけで、結合があるSQLではNULL=NULLは成立しない方がいいから、is NULLがあった方がいいらしーよ
アフロ:そうかー、じゃあちゃんとis NULLを使ってうちの会社でボーナスがNULLの社員を検索しなおすかー
SELECT 社員名, ボーナス FROM 社員 WHERE ボーナス is NULL;
アフロ | NULL |
おー、ちゃんと取れたな。わしのボーナスがNULLっと…
息子氏:でもNULLはまだ不明ってことだから、もしかしたら更新されて出るかもしれないらしーよ
(おしまい)
※当記事はアフロの個人的な見解を含みます
結びのメッセージ
Switch with us!
採用エントリー
ご応募はこちら