SQLのサブクエリを覚えよう!(SELECT、UPDATE、INSERTでの使い方)

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

今回の初心者訓練所#09は、SQL文の色々な所に登場する「サブクエリ」について説明していきます。ちょっと敬遠されがちな「サブクエリ」も、出現パターンを覚えてしまえば怖くはありません。パターンが複数におよぶため、2回に分けて紹介しますが、登場する場所ごとに使い方を説明しますので、しっかり覚えていってください。

「サブクエリ」って何? 

SQL文の問合せの事をクエリと呼びますが、サブクエリとは、その名の通りSQL文の中に入れ子でSQL文を記述することを指し、「副問合せ」とも呼ばれます。SELECT文やFROM句、WHERE句、もちろん、INSERT文やUPDATE文など、様々なところで使用できます。
サブクエリのメリットとして、複数のSELECT文を1つにまとめて記述できたり、複雑なテーブル結合を使わずに記述できたりという点があります。一方、デメリットとして、処理速度が遅くなる場合がありますので、使用には注意が必要です。

下表が、使われ方のイメージになります。

使われる場面 クエリのイメージ

SELECT:結果の値を項目として使用

SELECT a , (SELECT b FROM tbl_b)  FROM tbl_a;
UPDATE:項目を結果で更新 UPDATE tbl_a SET a = (SELECT b FROM tbl_b);
INSERT:結果でデータを作成 INSERT INTO tbl_a  ( a , b ) 
SELECT a , b FROM tbl_b;
FROM句:結果をテーブルとして使用 SELECT sub.a , sub.b
FROM (SELECT a , b FROM tbl_b) AS sub;
WHERE句:結果を存在チェックに使用 SELECT a , b FROM tbl_a 
WHERE c IN (SELECT c FROM tbl_c WHERE d > 10)
 
それでは、使われ方の詳細について説明していきます。 

SELECT:サブクエリの値を項目として使用するケース

はじめに、SELECT文でサブクエリの値を取得するケースを確認してみましょう。
今回もインストールが簡単なデータベース、「SQLite」を使用して説明していきます。

いつもの社員テーブル(tbl_employees)と、部署テーブル(tbl_dept)を使用して説明していきます。それぞれのcreate文とinsert文は以下となります。

【社員テーブルのcreate文とinsert文】

create table tbl_employees (emp_code integer , emp_name text , kana text , gender text , age integer , dept_code integer);
insert into tbl_employees (emp_code,emp_name,kana,gender,age,dept_code) values
('1','HoriiTaro','ホリイタロウ','M','40','1')
, ('2','IshimuraHana','イシムラハナ','F','33','2')
, ('3','KitajimaRuna','キタジマルナ','F','45','3')
, ('4','MuroiYuri', 'ムロイユリ','F', '27','1')
, ('5','KitazawaAika','キタザワアイカ','F','33','1')
, ('6','MitaniKoukiti','ミタニコウキチ','M','23','2');

sql09-01

出力フォーマットを調整して、select文で登録内容を確認してみましょう。

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

select * from tbl_employees;

sql09-02

insert文で作成した6件のデータを確認できます。

【部署テーブルのcreate文とinsert文】

create table tbl_dept (dept_code integer , dept_name text, valid_flg integer , update_user_id text);
insert into tbl_dept (dept_code , dept_name , valid_flg , update_user_id ) values
 ('1','技術部','1','YAMADA'), ('2','人事部','1','YAMADA')
, ('3','総務部','1','TANAKA'), ('4','経理部','0','SATO');

sql09-03

select文で登録内容を確認してみましょう。

select * from tbl_dept;

sql09-04

insert文で作成した4件のデータを確認できます。

それでは、SELECT文のサブクエリを確認してみましょう。

select emp_name
    , ( SELECT dept_name FROM tbl_dept AS dp 
        WHERE  dp.dept_code = emp.dept_code)  AS dept_name
from tbl_employees as emp;

sql09-05

SELECT文中のサブクエリで、社員テーブルの「dept_code」に一致する部署テーブルの「dept_name」を取得していることが確認できます。

ここで、3点ポイントがありますので注意してください。
(1)SELECT文でサブクエリを使用する場合は、サブクエリの結果を見易いように
   AS句を使用して別名にしましょう。
(2)サブクエリの結果は、必ず1行となるクエリを記述しましょう。
(3)サブクエリは、カッコ()で囲みましょう。

参考までに、サブクエリを使用しない内部結合で記述した場合は以下となります。

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

sql09-06

UPDATE:項目をサブクエリの値で更新するケース

次は、UPDATE文中で、サブクエリの情報で更新するケースを確認してみましょう。

確認準備のために、新たに会社テーブル(tbl_company)を作成して、データを挿入します。

【会社テーブルのcreate文】

create table tbl_company (comp_code text,comp_name text,admin_id text);
insert into tbl_company (comp_code,comp_name,admin_id) values
 ( '1' , '(株)BOOTCAMP' , 'SYSTEM' );

sql09-07

それでは、サブクエリを利用して、部署テーブルの更新者IDを会社テーブルの管理者IDで更新してみましょう。

update tbl_dept
set update_user_id = ( SELECT admin_id FROM tbl_company );

select * from tbl_dept;  -- 更新結果の確認

sql09-08

部署テーブルの更新者IDが、サブクエリで取得した会社テーブルの管理者IDで更新されていることが確認できます。UPDATE文で使用する場合も、SELECT文で使用する場合と同様にサブクエリの結果は1つであること、および、サブクエリはカッコ()で囲む必要がありますので注意してください。

INSERT:サブクエリの値でデータを作成するケース

続いて、サブクエリで取得したテーブルの値で、データを挿入するケースを確認してみましょう。データを複写する場合に、よく利用されます。

確認準備のために、追加でバックアップ部署テーブル(bkup_dept)を作成します。

【バックアップ部署テーブルのcreate文】

create table bkup_dept ( dept_code integer , dept_name text );

sql09-09

では、サブクエリで取得した部署テーブルの内容で、バックアップ部署テーブルにデータを挿入してみましょう。。

insert into bkup_dept (dept_code , dept_name)
SELECT dept_code , dept_name FROM tbl_dept;

select * from bkup_dept; -- 挿入結果の確認
  sql09-10

バックアップ部署テーブルに、サブクエリで取得した部署テーブルのデータが挿入されていることが確認できます。通常のINSERT文で使用する「VALUE」は記述しないでサブクエリを記述します。抽出条件が必要な場合は、サブクエリにWHERE句を追加して条件に一致するデータのみ挿入することもできます。

今回の説明は以上となります。

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

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

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

SQLの教科書
・一般的な解説から、実際にSQLを動かす操作イメージまで幅広く解説する資料です。
 「SQLの教科書」ビックデータ時代の必須科目

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

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

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

まとめ

今回は、初心者訓練所の第9弾として「サブクエリ」について、SELECT文、UPDATE文、INSERT文での使い方を紹介しました。使い方のイメージはつかめたでしょうか。サブクエリに慣れるにも、やはり実践の積み重ねが必要なので色々試してみて是非、習得してください。次回は、引き続きFROM句、WHERE句での使い方を説明していきます。それでは、次の初心者訓練所でまたお会いしましょう!

(株)システムインテグレータ インキュベーション部 元鬼軍曹 久保 司


RELATED POST関連記事


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


SQL‐BOOTCAMP

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

SQL‐BOOTCAMP

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

SQL‐BOOTCAMP

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

SQL‐BOOTCAMP

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

SQLのサブクエリを覚えよう!(SELECT、UPDATE、INSERTでの使い方)

TOPSIC TOPへ