はじめに
現在「達人に学ぶSQL徹底指南書」を読みながらSQLを学習中のTairaです
SQLを学んでいると必ず出てくるのが、
- サブクエリ
- 相関サブクエリ
です。
どちらも「SELECTの中にSELECTを書く」構文ですが、
評価のされ方 がまったく異なります。
本記事では、
いつ・何回・どう評価されるか
という視点で違いを整理します。
サブクエリとは?
サブクエリとは、SQL文の中に書かれたSELECT文のことです。
SELECT *
FROM employees
WHERE salary > (
SELECT AVG(salary)
FROM employees
);
この例のポイントは、
- 内側のSELECTが 外側の行を参照していない
- 内側のSELECTは 先に1回だけ評価される
という点です。
評価の流れ
- 内側の
SELECT AVG(salary)が実行される - 平均値が確定する
- 外側のSELECTで
salary > 平均値を評価する
👉 これが 非相関サブクエリ です。
(補足)サブクエリとビューの違い
ここで、ビュー(VIEW)との関係を簡単に整理しておきます。
ビューは、
SELECT文を「保存」したもの
です。
CREATE VIEW avg_salary_view AS
SELECT AVG(salary) AS avg_salary
FROM employees;
このビューを使うと、先ほどのサブクエリは次のように書けます。
SELECT *
FROM employees
WHERE salary > (
SELECT avg_salary
FROM avg_salary_view
);
やっていること自体は ほぼ同じ です。
サブクエリとビューの違い(要点だけ)
| 項目 | サブクエリ | ビュー |
|---|---|---|
| 正体 | その場のSELECT | SELECT文を保存 |
| 名前 | なし | あり |
| 再利用 | できない | できる |
そのため、
- 非相関サブクエリ = 名前のない一時ビュー
- ビュー = 名前付きのサブクエリ
と考えて問題ありません。(ただし、以下の注意点を確認してください)
注意点
ビューは SELECT文を保存しているだけ なので、
- DBによってはオプティマイザがビューの中身を十分に展開できず
- 結果として サブクエリより実行計画が不利になる可能性 もあります
👉 ビューはパフォーマンス改善の仕組みではなく、主目的は可読性・再利用性の向上 です。
相関サブクエリとは?
次に相関サブクエリです。
SELECT *
FROM employees e1
WHERE salary > (
SELECT AVG(salary)
FROM employees e2
WHERE e2.department_id = e1.department_id
);
ここが決定的な違いです。
e2.department_id = e1.department_id
内側のSELECTが、外側の行(e1)を参照 しています。
相関サブクエリの評価のされ方
相関サブクエリは、次のように評価されます。
- 外側の1行目が確定
- その行の値を使って内側のSELECTを実行
- 条件を満たすか判定
- 次の行へ進む
- これを 行数分繰り返す
つまり、
- 内側のSELECTは 行ごとに評価される
- 結果が 外側の行に依存 する
👉 これが 相関サブクエリ です。
両者の違いまとめ
| 観点 | サブクエリ | 相関サブクエリ |
|---|---|---|
| 外側の行を参照 | しない | する |
| 内側の評価回数 | 1回 | 行数分 |
| 行ごとの評価 | なし | あり |
| イメージ | 定数・集合 | 行単位の判定 |
なぜ相関サブクエリは特別扱いされるのか
相関サブクエリは、
- EXISTS / NOT EXISTS
- 「この行に対応するデータが存在するか」
といった 行ごとの存在判定 に非常に向いています。
一方で、
- 評価回数が増えやすい
- 大量データでは重くなりやすい
ため、Window関数やJOINに置き換えられることも多いです。
まとめ
- サブクエリは 1回評価される
- 相関サブクエリは 行ごとに評価される
- ビューは SELECT文を保存したもの
- ビューは可読性向上の仕組みであり、必ずしも高速とは限らない
- SQLでは 「評価のされ方」 を意識することが重要