【SQL】EXISTS句とは?EXISTS句の構文や使い方を詳しく解説

  • 2025.04.03
       
【SQL】EXISTSの使い方をサンプルコードで解説

本記事ではSQLがよくわからないという人に向けて、SQL文法のなかでも難易度の高い「EXISTS」の基礎から使い方、類似文法との違いまで解説します。今後のSQL学習の参考にしてみてください。

EXISTSを学ぶ上でのSQLの予備知識

データベースは集約・整理したデータを保管・管理する、いわば「帳簿」のようなシステムです。SQLはそのデータベースにアクセスしてデータを操作するための言語で、データの取得・追加・更新・削除ができます。SQLにはMySQLやPostgreSQLなどさまざまなデータベース管理システムが存在しますが、SQL言語はおおよそ共通したものが使用されています。

データベース管理システムに対する命令文をクエリ(問合せ)といいます。クエリには文(statement)、句(clause)、関数(function)などの分類に分かれていくつものキーワードが設定されており、そのキーワードを適切な順番で組み合わせることで、データベースの中から必要な情報を検索、取得、更新することができます。

本記事で紹介する「EXISTS」は句(clause)という種類のクエリで、「SELECT」などの実際にデータベースに対して行う処理を命令する文(statement)を補足する構成要素になります。

「EXISTS」は文を構成する句の1つなので、それだけで命令を記述することはできません。そのため、文の中で使用します。また、EXISTS句を使用する場合は、同時に「サブクエリ」という命令を記述することになります。

EXISTS句の概要とサブクエリの基礎知識

EXISTSとは?

SQLの「EXISTS」とは、指定された条件にあてはまるレコードが存在するか否かを調べるのに使用される句です。
EXISTS句は必ずサブクエリと併用され、サブクエリで1つ以上あてはまるレコードが存在した場合は「TRUE」を返し、そうでない場合は「FALSE」を返します。

データベーステーブルのカラムに対して複雑な条件を付けてレコードを取り出す場合、それぞれの条件に合わせてSELECT文を複数回使用するという方法をとることも考えられるかもしれません。
ですが、膨大な量のテーブルデータのなかから特定のデータを出力するために何度も同じような処理を繰り返すのは効率が悪く、データベースの処理も重くなるのでスマートな方法ではありませんね。

そんなとき、EXISTS句を使用して条件を細かく絞り込めば効率的に必要な情報を取り出すことができます。

なお、条件付きで出力を行う場合はIN句やJOIN句などを使うことも可能ですが、EXISTSを使えばより簡単に条件付きのSELECT文を記述できます。

【使用イメージ】

select * from テーブルA  //外側のSQL
where exists (
	select * from テーブルB  //EXISTS内のSQL
)

EXISTS句は、特定の条件にあてはまるレコードが存在するか否かを調べるのに使用されます。そのため、サブクエリで具体的な値を返す必要はなく、少なくとも1行のレコードがあてはまるかどうかで「TRUE」または「FALSE」を返すだけです。

そのため、サブクエリのSELECT文では、具体的な値ではなく、単に「SELECT *」や「SELECT 1」と書くのが一般的です。

サブクエリとは?

「サブクエリ」とは、メインクエリ内にネスト(入れ子)されたクエリのことです。SQL文の一部として内部で実行され、その実行結果をメインクエリに提供します。SELECT文を使用する際によく用いられ、日本語では「副問い合わせ」とも呼ばれます。条件を指定したデータの出力を行うには「サブクエリ」が有効です。たとえば、3000件の社員データが格納されているテーブルから「平均年齢よりも高い社員だけを出力する」といった条件をつけることができます。サブクエリを含んだクエリは先にサブクエリから実行され、その実行結果を一つのテーブルと見なしてメインクエリが実行されます。

【where句のサブクエリ記述例】

select * from テーブルA
where 項目 > (select 項目 from テーブルB where 条件);

サブクエリの使用例

【売り上げテーブル】

+------------+------------+--------+
| 氏名       | 社員コード | 売上額 |
+------------+------------+--------+
| 佐藤 太郎  | 10001      | 200    |
| 鈴木 次郎  | 10002      | 150    |
| 高橋 三郎  | 10003      | 100    |
+------------+------------+--------+

【実行クエリ】

select 氏名,売上額 from 売り上げ
where 売上額 > (select AVG(売上額) from 売り上げ);

【結果】

+------------+--------+
| 氏名       | 売上額 |
+------------+--------+
| 佐藤 太郎  | 200    |
+------------+--------+

まず、(select AVG(売上額) from 売り上げ)の部分で社内全員の売上額の平均値を計算します。

この部分がサブクエリです。
そして、メインクエリで平均値よりも高い売上額を出している社員を表示しています。

「select 1」や「select *」の意味

重複しますが、サブクエリでは具体的な値ではなく、1つ以上のレコードが存在するか否かを返します。そのため、何かしらの値(引数)を入れる必要はありますが、任意の値でいいので、とりあえず「*」や「1」を使うのが一般的です。ただ、データ読み込みの観点から「*」よりも「1」などの文字が好ましいです。

SELECT文の使い方については、こちらの記事で詳しく解説しています。

あなたのご希望に沿った案件が必ず見つかります
【フリーランス向け】高収入好待遇の案件をご紹介

TECH MANIA フリーランス

≫まずは簡単60秒で無料お問い合わせから≪

EXISTSの使用例

例として、1つ以上の商品を購入したユーザを出力します。

【ユーザテーブル】

+------------+----------+
| ユーザ名   | ユーザID |
+------------+----------+
| 佐藤 太郎  | 100001   |
| 鈴木 次郎  | 100002   |
| 高橋 三郎  | 100003   |
+------------+----------+

【注文テーブル】

+----------+--------+
| ユーザID | 注文数 |
+----------+--------+
| 100001   | 2      |
| 100003   | 1      |
+----------+--------+

【EXISTSのサンプルクエリ】

select * from ユーザ
where exists (select 1 from 注文 where ユーザ.ユーザID = 注文.ユーザID);

ポイント①

「ユーザ.ユーザID」「注文.ユーザID」という表記ですが、こちらは「テーブル名.要素名」という意味で、どのテーブルの何の項目なのかを指定しています。

ポイント②

上記2つのテーブルには、どちらにも「ユーザID」が記入されています。メインクエリで参照したテーブル上の値がサブクエリで参照したテーブル上の値と一致する場合に「TRUE」を返します。テーブル同士の紐づけをしないと、すべてのユーザが表示されてしまいます。

【結果】

+------------+----------+
| ユーザ名   | ユーザID |
+------------+----------+
| 佐藤 太郎  | 100001   |
| 高橋 三郎  | 100003   |
+------------+----------+

WHERE以下の条件が「TRUE」になるユーザのレコードを抽出します。

先述のポイント②でも紹介しましたが、テーブル同士を紐づけるか否かで出力されるデータが異なります。

紐づけを行わない場合は、サブクエリ(EXISTSの後ろに書かれる括弧の内側のSQLクエリ)で条件にあてはまる値が存在した場合に、メインクエリ(外側のSQLクエリ)が実行されます。値が存在しない場合は、メインクエリは実行されません。これを「存在判定」といいます。

一方で、紐づけを行う場合は、メインクエリが実行されてからサブクエリがメインクエリを参照して実行されます。これを「相関副問合せ」といいます。

EXISTS句はどういうときに使うと便利?

SQLを使用する際に、実際にEXISTS句を利用することになるケースの例を挙げてみました!

GROUP BYなどでの絞り込みからさらに特定の条件で絞り込みたいといったケースで使用することが多くなります。

  • 「ユーザ」のうち少なくとも1つの商品を購入した「ユーザ」を出力したい
  • 「社員データ」のうち「部署コード」が「2」の「社員レコード」を出力したい
  • 「企業データ」のうち「カテゴリー」が「IT」の「企業レコード」を出力したい
  • 「社員データ」と「部署データ」のうち、「社員データ」の「ID」と「部署データ」の「社員ID」が一致し、且つ、「部署コード」が「3」の「社員レコード」を出力したい

実際の利用例

在庫管理システム

在庫管理システムでは、EXISTS句を用いることで、サブクエリで「在庫テーブル」のうち、該当する商品在庫が1つ以上あるかどうかを確認できます。

データ分析

データ分析では、特定の条件を満たすデータがあるかどうかを調べるのにEXISTS句が利用されます。たとえば、「商品購入テーブル」対象の期間で特定の商品を購入したユーザを調べるといったこともできます。

NOT EXISTS句とは?

NOT EXISTS句とは、EXISTS句と反対の機能を持ち、特定の条件にあてはまるレコードが存在しない場合に「TRUE」を返し、存在する場合に「FALSE」を返します。

NOT EXISTSの使用例

【ユーザテーブル】

+------------+----------+
| ユーザ名   | ユーザID |
+------------+----------+
| 佐藤 太郎  | 100001   |
| 鈴木 次郎  | 100002   |
| 高橋 三郎  | 100003   |
+------------+----------+

【注文テーブル】

+----------+--------+
| ユーザID | 注文数 |
+----------+--------+
| 100001   | 2      |
| 100003   | 1      |
+----------+--------+

【NOT EXISTSを使用するクエリ例】

select * from ユーザ
where not exists (select 1 from 注文 where ユーザ.ユーザID = 注文.ユーザID);

【結果】

+------------+----------+
| ユーザ名   | ユーザID |
+------------+----------+
| 鈴木 次郎  | 100002   |
+------------+----------+

EXISTS句と類似文法の比較

EXISTSとINの比較

EXISTS句とIN句はどちらもサブクエリを扱いますが、EXISTS句が存在の有無のみを出力するのに対し、IN句は条件にあてはまるコードをすべて出力し、メインクエリで値を比較します。また、IN句はカラム名を指定する必要がありますが、EXISTS句では不要です。EXISTS句は条件にあてはまるレコードが存在した時点で検索を打ち切るため、IN句よりもパフォーマンスが優れているといわれています。そのため、具体的な値を比較する場合はIN句、特定の条件にあてはまるレコードの有無のみを確認するにEXISTS句を使いましょう。

EXISTSとJOINの比較

JOIN句は複数のテーブルを結合して1つの結果を出力しますが、EXISTS句はテーブルの結合をしません。よって、結合結果全体を出力させる場合はJOIN句、特定の条件にあてはまるレコードの有無のみを知りたい場合はEXISTS句を使いましょう。

EXISTSと通常の比較演算子の比較

比較演算子は2つの値を比較して出力を行います。そのため、値同士を比較する必要がある場合は比較演算子、特定の条件にあてはまるレコードの有無のみを知りたい場合はEXISTS句を使いましょう。

UPDATE句との組み合わせ

実は、EXISTSを使うのは、SELECT文だけではありません。メインクエリにUPDATE句を用いることで、該当するデータのみを更新することもできます。

EXISTSを使うときに気を付けることは?

非常に便利なEXISTS句ですが、クエリの中に組み込む際はいくつか注意すべきポイントがあります。

クエリを工夫しないとパフォーマンスが下がりやすい

EXISTSを使用してレコードの有無を確認すると、参照したテーブルの総レコード数に応じて比較処理が実行されます。指定した条件に合致するレコードがあればそこで処理は終了しますが、存在しない場合は全てのレコードをチェックするので、レコード数が多くなればなるほど処理は遅くなりやすいという欠点があります。

実際のクエリで使用する場合には適切なインデックスを設定し、LIMIT句でデータ量を制限するなどの工夫をするように意識しましょう。

EXISTSもセキュリティの脆弱性につながる場合がある

SQLには「SQLインジェクション」というサイバー攻撃の手法があり、適切な対策を取らないと機密情報の流出やデータベースの破壊といった損害を受ける場合があります。

EXISTSを使用する場合も例外ではなく、データベースに情報を入力する際は記号をエスケープ(プログラムにおける各種記号の文字が持つ機能を喪失させ、ただの文字と認識させるようにする処理)したり、プレースホルダー(特定の記号や文字を事前に入れておき、実際の値はその文字にあとから代入する方法)を用いたりするなどの対策を取る必要があります。

特にSQLインジェクションによるサイバー攻撃は毎年多くの企業で発生し、多大な損害を与えています。業務でSQLを使う場合には、しっかりと意識しておきたいですね。

SQLの勉強方法は?

書籍やインターネットで学習する方法があります。昨今では、YouTubeなどの動画サイトやエンジニアのコミュニティサイトなども充実していて多くの情報が手に入ります。
そして、より効率的に知識・スキルを習得するには、知識をつけながら実際に手を動かしてみるなど、インプットとアウトプットを繰り返していくことが重要です。特に独学の場合は、有識者に質問ができたりフィードバックをもらえるような環境があると、理解度が深まるでしょう。

ただ、SQLに限らず、ITスキルを身につける際、どうしても課題にぶつかってしまうことはありますよね。特に独学だと、わからない部分をプロに質問できる機会を確保しにくく、モチベーションが続きにくいという側面があります。独学でモチベーションを維持する自信がない人にはプログラミングスクールという手もあります。費用は掛かりますが、その分スキルを身につけやすいです。しっかりと知識・スキルを習得して実践に活かしたいという人はプログラミングスクールがおすすめです。

プログラミングスクールならテックマニアがおすすめ!

ITスキル需要の高まりとともにプログラミングスクールも増えました。しかし、どのスクールに通うべきか迷ってしまう人もいるでしょう。そんな方にはテックマニアをおすすめします!これまで多くのITエンジニアを育成・輩出してきたテックマニアでもプログラミングスクールを開講しています。

<テックマニアの特徴>
・たしかな育成実績と親身な教育 ~セカンドキャリアを全力支援~
・講師が現役エンジニア ~“本当”の開発ノウハウを直に学べる~
・専属講師が学習を徹底サポート ~「わからない」を徹底解決~
・実務ベースでスキルを習得 ~実践的な凝縮カリキュラム~

このような特徴を持つテックマニアはITエンジニアのスタートラインとして最適です。
話を聞きたい・詳しく知りたいという方はこちらからお気軽にお問い合わせください。

     

Otherカテゴリの最新記事