はじめに
SQLにおけるサブクエリとは、別のSQL文の内部に埋め込まれたSELECT文のことです。外側のクエリが内側のクエリの結果を利用して複雑な処理を行います。
使用データ
Employeesテーブル

Departmentsテーブル

Ordersテーブル

Where句における使用
最も一般的な使い方でWhere句で使う場合は条件にサブクエリを使ってフィルタリングします。
例えば平均給与より高い社員を取得する場合
クエリ
SELECT name, salary
FROM employees
WHERE salary > (SELECT AVG(salary) FROM employees);
サブクエリのSELECT AVG(salary) FROM employeesが実行されメインクエリが実行されます
サブクエリの実行結果
| AVG |
|---|
| 522000.0000 |
クエリの実行結果
| name | salary |
|---|---|
| 佐藤健一 | 610000 |
| 高橋翔 | 530000 |
| 伊藤直樹 | 700000 |
| 小林由美 | 550000 |
相関サブクエリ
先ほどのクエリはすべての行で同じサブクエリで使っていたが、相関副問い合わせはメインクエリの値を参照することを可能にする。外側の行が1行処理されるたびに、その行の値を使って副問合せが実行されます。つまり「行ごとに問い合わせ内容が変わる」のが特徴です。
「自分と同じ部署の平均給与」より高い社員を取得する場合
クエリ
SELECT e.name, e.dept_id, e.salary
FROM employees e
WHERE e.salary > (
SELECT AVG(e2.salary) FROM employees e2 WHERE e2.dept_id = e.dept_id);
WHERE e2.dept_id = e.dept_idで外側の行を参照し行ごとに異なるクエリになります。サブクエリで自分と同じ部署の平均給与が導出されます。
dept_id = 1の時のサブクエリの実行結果
| AVG(salary) |
|---|
| 595000.0000 |
クエリの実行結果
| name | dept_id | salary |
|---|---|---|
| 佐藤健一 | 1 | 610000 |
| 山田美咲 | 3 | 450000 |
| 高橋翔 | 2 | 530000 |
| 伊藤直樹 | 1 | 700000 |
| 加藤誠 | 3 | 470000 |
FROM句での使用
副問合せの結果を仮想的なテーブルとして扱います。
受注件数と受注合計額を社員情報と並べて表示
クエリ
SELECT e.name, t.order_count, t.total_amount
FROM employees e
JOIN (
SELECT emp_id,
COUNT(*) AS order_count,
SUM(amount) AS total_amount
FROM orders
GROUP BY emp_id
) AS t ON e.emp_id = t.emp_id;
サブクエリ
クエリ全体が複雑なためサブクエリで受注件数と受注合計額を求めます
SELECT emp_id,
COUNT(*) AS order_count,
SUM(amount) AS total_amount
FROM orders
GROUP BY emp_id
サブクエリの実行結果
| emp_id | order_count | total_amount |
|---|---|---|
| 2 | 4 | 4350000 |
| 5 | 3 | 8100000 |
| 8 | 3 | 3600000 |
クエリの実行結果
社員の名前が必要なためemployeeテーブルと結合
| name | order_count | total_amout |
|---|---|---|
| 鈴木花子 | 4 | 4350000 |
| 高橋翔 | 3 | 8100000 |
| 中村大輔 | 3 | 3600000 |
SELECT句での使用
複雑なカラム計算をSELECT句内で完結できます
各社員の名前と、その社員の受注件数を並べて表示
クエリ
SELECT e.name,
e.salary,
(SELECT COUNT(*) FROM orders o WHERE o.emp_id = e.emp_id) AS order_count
FROM employees e;
emp_id=1の時のサブクエリの実行結果
SELECT句で使われるサブクエリはレコード1行に対して1回実行される相関サブクエリであるので
| name | salary | order_count |
|---|---|---|
| 田中太郎 | 520000 | 0 |
クエリの実行結果
| name | salary | order_count |
|---|---|---|
| 田中太郎 | 520000 | 0 |
| 鈴木花子 | 480000 | 4 |
| 佐藤健一 | 610000 | 0 |
| 山田美咲 | 450000 | 0 |
| 高橋翔 | 530000 | 3 |
| 伊藤直樹 | 700000 | 0 |
| 渡辺あかり | 420000 | 0 |
| 中村大輔 | 490000 | 3 |
| 小林由美 | 550000 | 0 |
| 加藤誠 | 470000 | 0 |
まとめ
サブクエリはSQL学習の中でも特に難しい分野です。
しかしサブクエリを理解することができれば複雑なクエリも簡潔に記述することができるできます。
是非、実戦でも活用して業務を効率化してみてください。

