SQLでSELECTを使ったクエリは多々ありますが、その一つに「副問い合わせ」というものがあります。
学習を始めたばかりの方には聞きなれないワードだと思いますが、覚えると非常に便利にINSERTやUPDATEが行えるようになります。
そこで今回はこの「副問い合わせ」について解説してみたいと思います。
副問い合わせとは

副問い合わせとは、入れ子になったSQL文の呼称で「サブクエリ」とも呼ばれています。
もう少し厳密に言うと、通常は入れ子になったSQL文の内側に記述されているSQL文を指します。
例えば次のようなコードがあるとします。
SELECT
count(*)
FROM (
SELECT
[カラム名]
FROM
[テーブル名]
WHERE
[条件]
)
;
このコードの副問い合わせ部分は4行目~10行目となります。
副問い合わせを使うケース
副問い合わせを使うケースは様々ですが、上に記述したコードが基本形となります。
但し、FROMの中で使用することが基本形という意味ではないので注意してください。あくまでも副問い合わせの形という意味です。
上のコードについて順を追って説明すると次のようになります。
1. あるテーブルから抽出したいデータの条件を指定する。
2. 指定された条件に合うデータが全て抽出される。
3. 福問い合わせで抽出されたデータ件数をカウントする。
副問い合わせと聞くと小難しいかもしれませんが「[SQL文の実行により返された結果]を使ったSQL文」と考えると理解できるのではないでしょうか。
また今回はSELECT文を使ったコードで解説したためFROM内にサブクエリを記述しましたが、サブクエリ自体はWHERE句を使った条件式やINSERT文及びUPDATE文などでも使用できます。
副問い合わせを使ったUPDATE

ここまでは副問い合わせの基本概念について解説してきました。
ここからはこの副問い合わせを使ったUPDATE文の記述方法について解説していきたいと思います。
今回のサンプルコードで使用するテーブルは以下の通りです。
// table_stuff(社員基本データ)
id name age code job
----------- ---------- ----------- ---------- --------------------
1 Alex 26 A0001 NULL
2 Smith 21 A0002 NULL
3 Tomath 29 A0003 NULL
4 Porl 20 A0004 NULL
5 Sophia 40 A0005 NULL
// table_job(社員職種)
code job
---------- --------------------
A0001 programmer
A0002 sales
A0003 designer
A0004 programmer
A0005 officer
次に記述するサンプルコードでは、table_stuff(社員基本データ)の社員の職種を変更しています。
UPDATE
table_stuff
SET
table_stuff.job = (
SELECT
job
FROM
table_job
WHERE
table_job.code = table_stuff.code
);
GO
(5 行処理されました)
SELECT * FROM table_stuff;
GO
id name age code job
----------- ---------- ----------- ---------- --------------------
1 Alex 26 A0001 programmer
2 Smith 21 A0002 sales
3 Tomath 29 A0003 designer
4 Porl 20 A0004 programmer
5 Sophia 40 A0005 officer
4行目~サブクエリを使用していますが、変更を行うべき値を取ってくるために「SELECT job FROM table_job」とすることで値を指定できます。
またWHEREで条件指定する際、table_job(社員職種)の「table_job.code」とtable_stuff(社員基本データ)の「table_stuff.code」を比較してテーブル間の紐付けを行っています。
WHEREの中で使用する場合にはEXISTSが必要
サブクエリはWHEREの中でも使用することが出来ますが、WHEREの中で使用するにはEXISTSを使用する必要があります。
まず次のコードを見てください。
UPDATE
table_stuff
SET
table_Stuff.job = NULL
WHERE (
SELECT
job
FROM
table_job
WHERE
table_job.code = table_stuff.code
);
GO
メッセージ 4145、レベル 15、状態 1、サーバー DESKTOP-T3J7G2K\SQLEXPRESS、行 12
条件が必要なコンテキストに対し、';' 付近でブール型以外の式が指定されました。
あこのコードは、先ほど変更したtable_stuffのカラム「job」を再度”NULL”に変更するためのコードですが、エラーメッセージが表示されています。
それでは更に次のコードを見てみましょう。
UPDATE
table_stuff
SET
table_Stuff.job = NULL
WHERE EXISTS (
SELECT
job
FROM
table_job
WHERE
table_job.code = table_stuff.code
);
GO
(5 行処理されました)
SELECT * FROM table_stuff;
GO
id name age code job
----------- ---------- ----------- ---------- --------------------
1 Alex 26 A0001 NULL
2 Smith 21 A0002 NULL
3 Tomath 29 A0003 NULL
4 Porl 20 A0004 NULL
5 Sophia 40 A0005 NULL
今度はきちんと成功しています。
上と下のコードの差はサブクエリを使用する直前の”WHERE”の後に「EXISTS」が在るか無いかだけの差です。
このようにサブクエリをWHERE内で使うためには必ず「EXISTS」が必要となるため、覚えておくようにしましょう。
まとめ
いかがでしたか?
今回はサブクエリの結果でUPDATEを行う方法について解説してみました。
SELECTを使ったクエリもこのように色々と存在します。
サブクエリを覚えることでSQLの操作にも幅が広がるため、この記事を読んでしっかりとマスターしてみてください!