まとめようとしたきっかけ
不具合を直そうと思ってexistsを使った結果、使い方を誤解していたために、別の新たな不具合を仕込みかけた
「select *」ではなく、存在チェックをしたかったカラムをピンポイントで取得しようとするときに(select nameなど)にハマった罠でした。
サンプルデータ
テーブル名:member
id | name | sex | div | age |
---|---|---|---|---|
1 | 田中 | 男 | 営業 | 25 |
2 | 佐藤 | 男 | 34 | |
3 | 池田 | 女 | 開発 | 28 |
select * の場合
特に問題ない。引っかかるポイントはないはず。
where sex = "男"
取得結果は・・・↓
id | name | sex | div | age |
---|---|---|---|---|
1 | 田中 | 男 | 営業 | 25 |
2 | 佐藤 | 男 | 34 | |
レコードが取得できたので、この時のexistsの結果は「1(true)」。 |
select exists (select * from member where sex = '男');
where div = "総務"
取得結果は・・・↓
id | name | sex | div | age |
---|---|---|---|---|
div = '総務'というレコードは存在しない=レコードが取得できないので、existsの結果は「0(false)」。 |
select exists (select * from member where div = '総務');
select divの場合
1カラムだけ取ってくるので、カラムの値とレコードの有無がごっちゃになってしまいがち
where name = "田中"
取得結果は・・・↓
div |
---|
営業 |
レコードが取得できているので、existsの結果は「1(true)」。 |
select exists (select div from member where name = '田中');
where name = "佐藤"
取得結果は・・・↓
div |
---|
レコードが取得できているので、existsの結果は「1(true)」。 |
select exists (select div from member where name = '佐藤');
ひっかかりポイント!
このselect文では1レコード取得できている。
select * from member where name = '佐藤';
あくまでも、divというカラムがnullとか空文字だっただけで、レコードとしては存在している。
そのため、existsは「1(true)」になる。
nullとか空文字であることを判定したいなら、ifnullとかがよい。