はじめに
業務や学習でSQLを読んでいると、次のような感じのコードを見かけることがありました
SELECT *
FROM customers c
WHERE EXISTS (
SELECT 1
FROM orders o
WHERE o.customer_id = c.id
)
初めて見たとき私は、
- EXISTSって何?
- なぜSELECT 1なの?
- customer_idを取得しないの?
と混乱しました。
今回は、SQL初心者の頃に疑問だった
SELECT 1って何?
という点を中心に整理してみます。
まずはEXISTSを日本語にしてみる
EXISTSは英語で
存在する
という意味です。
SQLでは
WHERE EXISTS (サブクエリ)
と書くことで
サブクエリの結果が1件でも存在するならOK
という判定になります。
サンプルデータで考える
customersテーブル
| id | name |
|---|---|
| 1 | 田中 |
| 2 | 鈴木 |
| 3 | 佐藤 |
ordersテーブル
| id | customer_id |
|---|---|
| 10 | 1 |
| 11 | 1 |
| 12 | 3 |
SQLを読んでみる
SELECT *
FROM customers c
WHERE EXISTS (
SELECT 1
FROM orders o
WHERE o.customer_id = c.id
)
私は最初、
SELECT 1
が意味不明でした。
SELECT 1って何?
実はEXISTSが見ているのは
どんな値が返ってきたか
ではありません。
見ているのは
行が存在するか
だけです。
例えば
SELECT 1
FROM orders
の結果は
| 1 |
|---|
| 1 |
| 1 |
| 1 |
のようになります。
EXISTSが見ているもの
EXISTSは
値
ではなく
行数
を見ています。
つまり
SELECT 1
でも
SELECT *
でも
SELECT customer_id
でも、
EXISTSの判定結果は同じです。
SQLの気持ちになってみる
例えば
WHERE EXISTS (
SELECT 1
FROM orders o
WHERE o.customer_id = c.id
)
を顧客ごとに見ると、
田中(id=1)
SELECT 1
FROM orders
WHERE customer_id = 1
結果
1
1
行が存在する
↓
TRUE
鈴木(id=2)
SELECT 1
FROM orders
WHERE customer_id = 2
結果
結果なし
行が存在しない
↓
FALSE
佐藤(id=3)
SELECT 1
FROM orders
WHERE customer_id = 3
結果
1
行が存在する
↓
TRUE
最終的な結果
TRUEになった顧客だけが残ります。
| id | name |
|---|---|
| 1 | 田中 |
| 3 | 佐藤 |
つまり
注文を1件以上持っている顧客
を取得しているSQLだったのです。
なぜSELECT 1がよく使われるの?
理由はシンプルです。
EXISTSは
存在するかどうか
しか見ていません。
そのため
SELECT customer_id
のように値を取得する必要がありません。
そこで
SELECT 1
と書いて
このSQLは値を取得したいわけではなく、存在確認をしたいだけです
という意図を表現しているのです。
まとめ
今回学んだことをまとめます。
- EXISTSは「存在するか」を判定する
- TRUE/FALSEで評価される
- EXISTSは値ではなく行の有無を見ている
- そのためSELECT 1で問題ない
- SELECT 1は「存在確認が目的」という意図を表している
私は最初、
SELECT 1って何を取得しているんだろう?
と思っていました。
しかし実際は、
何を取得するかではなく、行が存在するかを確認するための書き方
でした。
SQLを読むときにSELECT 1が出てきたら、
「値ではなく存在チェックをしているんだな」
と考えると理解しやすくなると思います。
