SQLのEXISTS句とサブクエリで存在チェック!

 2024.11.15  株式会社システムインテグレータ

今回の初心者訓練所#21は、WHERE句で使用されるサブクエリの結果が存在するかどうかを判定するEXISTS句について説明していきます。データの存在チェックをおこなう場合に、便利で可読性もよい方法なので、是非、使い方を覚えましょう。いつもの「SQLite」を使用して進めていきますので、「SQLite」をインストールしてから読み進めてください。

EXISTS句

EXISTS句は、WHERE句の条件文で使用され指定したサブクエリの結果が1件以上の行を返す場合に、「真(TRUE)」、それ以外は「偽(FALSE)」となります。結果が真となった場合にのみ、メインのクエリが実行されます。このように、特定の条件に一致するデータの存在チェックに便利な句です。
また、EXISTS句はサブクエリが結果を見つけた時点で評価を終了し無駄なデータの取得を行わないので、大規模なデータでチェックを行う場合に効率的に動作することがあります。ただし、サブクエリが非常に複雑な場合はパフォーマンスが低下する恐れがありますので注意してください。
構文は以下となります。

where EXISTS ( サブクエリ )

それでは、実際のデータを利用して確認するために、確認用の社員テーブル(tbl_employees)と部署テーブル(tbl_dept)を作成してデータを挿入してみましょう。

create table tbl_employees (emp_code integer, emp_name text, kana text , gender text , birthday text , dept_code integer);
create table tbl_dept (dept_code integer, dept_name text, valid_flg text);
insert into tbl_employees values 
    (101,'HoriiTaro','ホリイタロウ','M','1970-12-27',100)
  , (102,'IshimuraHana','イシムラハナ','F','1981-09-01',200)
  , (103,'KitajimaRuna','キタジマルナ','F','1981-11-30',300)
  , (104,'MuroiYuri','ムロイユリ','F','1982-02-12',400)
  , (105,'KitazawaAika','キタザワアイカ','F','1980-08-05',400)
  , (106,'MitaniKoukiti','ミタニコウキチ','M','1979-03-16',200);
insert into tbl_dept values 
    (100,'営業部','1')
  , (200,'人事部','1')
  , (300,'総務部','1');

blog-21-01

出力フォーマットを調整して、SELECT文でそれぞれのテーブルの登録内容を確認してみましょう。

.headers on (ヘッダ情報を出力)
.mode column (カラム毎に左揃え出力)

select * from tbl_employees;

select * from tbl_dept;

blog-21-02
社員テーブルに6件、部署テーブルに3件のデータが作成されていることが確認できます。

それでは、作成したデータからEXISTS句を使用して、社員テーブルの部署コードが部署テーブルに存在する社員のみを抽出してみましょう。

以下のSELECT文で確認してみましょう。

select emp.emp_name,emp.dept_code
  from tbl_employees as emp
where EXISTS ( select dp.dept_code
                           from tbl_dept as dp 
                         where dp.dept_code = emp.dept_code );
 
blog-21-03

EXISTS句のサブクエリで、社員テーブルのdept_code毎に部署テーブルのdept_codeを比較して、部署テーブルに該当するdept_codeが存在するかチェックを行っています。
部署テーブルに該当する部署コードが存在する場合のみ、社員テーブルの該当データが表示されます。
また、社員テーブルと部署テーブルに同じ項目名「dept_code」が存在するので、それぞれのテーブル名を別名(AS句)で「emp」「dp」に変換して、使用している項目がどのテーブルの項目か分かり易いようにしています。

補足情報となりますが、上記のサブクエリのように、親のクエリの値を基に実行されるサブクエリは、相関サブクエリとよばれます。

参考までに、上記のEXISTS句を使用したクエリを内部結合で記述すると下記の様になります。

select emp.emp_name,emp.dept_code
  from tbl_employees as emp
 INNER JOIN tbl_dept as dp ON dp.dept_code = emp.dept_code;

blog-21-04

EXISTS句のクエリと同じ結果になることが確認できます。
内部結合では、dept_codeで社員テーブルと部署テーブルを結合しているので、両方のテーブルにdept_codeが存在するデータが抽出されます。

NOT EXISTS句

EXISTS句とは逆に、条件に一致するデータが存在しない場合に、「真(TRUE)」、それ以外は「偽(FALSE)」を返す場合は、「NOT EXISTS」を使用します。

構文は以下となります。

where NOT EXISTS ( サブクエリ )

先程とは逆に、NOT EXISTS句を使用して、社員テーブルのdept_codeが部署テーブルに存在しない社員のみを抽出してみましょう。

以下のSELECT文で確認してみましょう。

select emp.emp_name,emp.dept_code
  from tbl_employees as emp
where NOT EXISTS ( select dp.dept_code
                                   from tbl_dept as dp 
                                 where dp.dept_code = emp.dept_code );

blog-21-05

部署テーブルに存在しない、dept_code「400」の2件が抽出されていることが確認できます。

参考までに、上記のNOT EXISTS句を使用したクエリを外部結合で記述すると下記の様になります。

select emp.emp_name,emp.dept_code
from tbl_employees as emp
  LEFT OUTER JOIN tbl_dept as dp ON dp.dept_code = emp.dept_code
where dp.dept_code IS NULL;

blog-21-06

内部結合と同様にdept_codeで外部結合しています。

外部結合では結合した結果、存在しないテーブルの項目は「NULL」となるので、
部署テーブルのdept_codeが「NULL」(社員テーブルに存在しているが、部署テーブルに存在していない)の条件を追加して、社員テーブルにのみ存在するデータを抽出しています。

参考までに、dept_codeが「NULL」の条件を外した場合は、以下の結果となります。

select emp.emp_name,emp.dept_code,dp.dept_code
from tbl_employees as emp
  LEFT OUTER JOIN tbl_dept as dp ON dp.dept_code = emp.dept_code;

blog-21-07
説明は以上となります。

おすすめの学習コンテンツ

本記事を読み終わって、さらに学びたい方、次は問題にチャレンジしてみたい方には、以下の無料コンテンツをご用意しておりますので、ぜひ活用してみてください!

SQLiteについて
・本記事で使用したデータベース「SQLite」について解説する資料です。
 SQLiteとは?他のデータベースとの違いも解説

SQLの教科書
 ビックデータ時代の必須科目「SQLの教科書」(初級編)
 ビックデータ時代の必須科目「SQLの教科書」(中級編 UPDATE文)
 ビックデータ時代の必須科目「SQLの教科書」(中級編 テーブル結合)
 ビックデータ時代の必須科目「SQLの教科書」(中級編 関数ピックアップ) NEW!!

SQL無料トライアルテスト
・TOPSIC-SQLの無料トライアルテストをご受験していただけます。
 TOPSIC-SQL無料トライアルテスト

SQLコンテスト
・簡単な会員登録をするだけでSQLのオンラインコンテストに無料で参加できます。
    過去に開催されたコンテストの問題にもチャレンジできます。
 TOPSIC SQL CONTEST

SQL基礎解説YouTube
・「TOPSIC-SQL」を元にしたオンラインウェビナーです。
 SQL-BOOT CAMP #1 
 ビッグデータ時代の必須科目SQLを学ぶ「実戦で通用する武器を身につけよう!」

あとがき

「初心者訓練所」の第21弾では、EXISTS句について説明してきました。EXISTS句は、特定の条件に一致するデータの存在を効率的に確認するための強力なツールであり、大規模なデータベースでのクエリ作成において特に役立ちます。EXISTS句をうまく活用して、今後の皆さんのデータベース操作やSQLクエリの作成がより効率的に進めることができれば幸いです。

(株)システムインテグレータ TOPSICチーム 元鬼軍曹 久保 司


RELATED POST関連記事


RECENT POST「SQL‐BOOTCAMP」の最新記事


SQL‐BOOTCAMP

SQLの便利な関数(NULLIF、IIF)を使ってみよう!

SQL‐BOOTCAMP

SQLのNULLを扱う関数(IFNULL、COALESCE)を使ってみよう!

SQL‐BOOTCAMP

SQLの日付・時間関数(DATE、TIME、DATETIME、JULIANDAY、STRFTIME)を使ってみよう!

SQL‐BOOTCAMP

SQLのウィンドウ関数(LAG、LEAD、FIRST_VALUE、LAST_VALUE、NTH_VALUE)を使ってみよう!

SQLのEXISTS句とサブクエリで存在チェック!

TOPSIC TOPへ