中学理科1626207 views
いろは2986023 views
高校化学2913383 views
高校生物549842 views
高校国語785655 views
Computer365120 views
世界の国560595 views
中学英語808712 views
りんご192546 views
ヒストリア284143 views
Help
Tools

English

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

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