【MySQL】existsの挙動まとめ

  • 1
    Like
  • 0
    Comment

まとめようとしたきっかけ

不具合を直そうと思ってexistsを使った結果、使い方を誤解していたために、別の新たな不具合を仕込みかけた:sweat_drops:
「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カラムだけ取ってくるので、カラムの値とレコードの有無がごっちゃになってしまいがち:droplet:

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とかがよい。