とあるサブクエリで抽出した条件にマッチするかどうかを抽出することができる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
クエリ実行結果