EXISTS で存在チェックをする
EXISTS は、サブクエリが結果を返すかどうかをチェックする演算子です。「関連するデータが存在するか」を調べるときに使います。
基本構文
SELECT * FROM テーブル
WHERE EXISTS (サブクエリ);サブクエリが 1 行でも結果を返せば TRUE、0 行なら FALSE になります。
具体例
「注文が 1 件以上あるユーザー」を取得するには、こう書きます。
SELECT * FROM users u
WHERE EXISTS (
SELECT 1 FROM orders o WHERE o.user_id = u.id
);サブクエリで SELECT 1 と書いていますが、EXISTS は「結果があるかどうか」だけを見るので、何を SELECT しても動作は同じです。
NOT EXISTS
逆に「存在しない」ことを確認するには NOT EXISTS を使います。
-- 注文が 1 件もないユーザー
SELECT * FROM users u
WHERE NOT EXISTS (
SELECT 1 FROM orders o WHERE o.user_id = u.id
);IN との違い
似たようなことは IN でもできます。
-- IN を使う場合
SELECT * FROM users
WHERE id IN (SELECT user_id FROM orders);
-- EXISTS を使う場合
SELECT * FROM users u
WHERE EXISTS (SELECT 1 FROM orders o WHERE o.user_id = u.id);どちらも「注文があるユーザー」を取得しますが、動きが少し違います。
IN
サブクエリの結果をリストとして取得し、照合する
EXISTS
外側の各行に対して、マッチする行があるかチェック
パフォーマンスの違い
一般的に、サブクエリが多くの行を返す場合は EXISTS のほうが速いことがあります。EXISTS は「1 行見つかった時点で終了」するためです。
-- orders が大量にあるとき、EXISTS のほうが速い可能性
SELECT * FROM users u
WHERE EXISTS (SELECT 1 FROM orders o WHERE o.user_id = u.id);ただし、インデックスの有無や データ量によって変わるので、実際に試してみるのが一番です。
EXISTS の使いどころ
関連データの存在確認
「コメントがある投稿」「注文がある顧客」など
NOT EXISTS で「ない」を探す
「在庫がない商品」「フォロワーがいないユーザー」など
EXISTS は特に NOT EXISTS で威力を発揮します。LEFT JOIN + IS NULL でも同じことができますが、EXISTS のほうが意図が明確になることがあります。
-- LEFT JOIN + IS NULL
SELECT u.* FROM users u
LEFT JOIN orders o ON u.id = o.user_id
WHERE o.id IS NULL;
-- NOT EXISTS(同じ意味)
SELECT * FROM users u
WHERE NOT EXISTS (SELECT 1 FROM orders o WHERE o.user_id = u.id);どちらを使うかは好みや状況によりますが、両方の書き方を知っておくと便利です。












