LaTeX958047 views
雑学1472809 views
数学講師2859838 views
小学理科717678 views
高校生物550134 views
高校物理158525 views
中学数学621831 views
高校倫理1434489 views
ヒストリア285220 views
中学社会667376 views

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);

どちらを使うかは好みや状況によりますが、両方の書き方を知っておくと便利です。