とあるサブクエリで抽出した条件にマッチするかどうかを抽出することができるEXISTS演算子の使い方について説明していきます。
通常SQLで抽出するにはWHERE区での条件指定を行います。また「○○が10件以上存在するデータ」のようにHAVINGを使った複雑な抽出条件の場合は、サブクエリとIN演算子を使って抽出する方法がありますが対象データが大量の場合はクエリの実行速度のパフォーマンスが遅かったりします。
そんな複雑な条件でデータを抽出したい場合は、EXISTS演算子を使いこなすことができればより速度を速く短いSQL文でデータを抽出することができます。
今回EXISTSを説明するにあたって下記のテーブル、データが存在するものとして進めていきます。
データ構造

顧客(customer)テーブル
| 顧客コード(code) | 名前(full_name) | 電話番号(tel) | 都道府県(prefecture) |
| C0001 | 佐藤 太郎 | 090-0000-1111 | 東京都 |
| C0002 | 山田 次郎 | 090-0000-2222 | 福岡県 |
| C0003 | 鈴木 三郎 | 090-0000-3333 | 大阪府 |
| C0004 | 斉藤 四郎 | 090-0000-1111 | 北海道 |
| C0005 | 渡辺 五郎 | 090-0000-5555 | 長崎県 |
商品(product)テーブル
| 商品コード(code) | 商品名(name) | 価格(price) |
| P0001 | 商品A | 1000 |
| P0002 | 商品B | 500 |
| P0003 | 商品C | 800 |
| P0004 | 商品D | 900 |
販売(sales_order)テーブル
| 注文番号(code) | 顧客コード (customer_code) | 商品コード (product_code) | 価格 (price) | 数量 (quantity) | 合計金額 (total_price) |
| SO0001 | C0001 | P0001 | 1000 | 1 | 1000 |
| SO0002 | C0002 | P0002 | 500 | 4 | 2000 |
| SO0003 | C0001 | P0003 | 800 | 2 | 1600 |
SQL
SELECT
C1.*
FROM
customer AS C1
WHERE
EXISTS(
SELECT
C2.tel
FROM
customer AS C2
WHERE
C1.tel = C2.tel
GROUP BY
C2.tel
HAVING
COUNT(C2.tel) > 1
)
ORDER BY C1.CODE ASC
クエリ実行結果

重複した番号を持たないデータを抽出する場合は①の逆の条件指定をすればいいので「EXISTS」を「NOT EXISTS」にするだけで抽出することができます
SQL
SELECT
C1.*
FROM
customer AS C1
WHERE
NOT EXISTS(
SELECT
C2.tel
FROM
customer AS C2
WHERE
C1.tel = C2.tel
GROUP BY
C2.tel
HAVING
COUNT(C2.tel) > 1
)
ORDER BY C1.CODE ASC
クエリ実行結果

SQL
SELECT
C.*
FROM
customer AS C
WHERE
EXISTS(
SELECT
*
FROM
sales_order AS S
WHERE
S.customer_code = C.code
)
ORDER BY C.CODE ASC
クエリ実行結果


