SQL文の中に入れ子で記述する別の問合せ。
副問合せ(サブクエリ)とは、1つのSQL文の中に、括弧でくくってもう1つのSELECT文を入れ子(ネスト)で書いたものです。外側の問合せが、内側の問合せの結果を材料として使います。
身近な例で考えると、「クラスの平均点を計算してから、その平均より高い人を選ぶ」という2段階の作業に似ています。先に平均(内側)を出し、その値を基準に選ぶ(外側)、という流れを1つのSQLにまとめたものです。
上のツールで▶ボタンを押すと、内側の副問合せが先に実行され、その結果が外側に差し込まれて最終結果が決まるまでの流れを確認できます。
副問合せは、返ってくる結果の形によって主に3種類に分けられます。
・スカラ副問合せ:値が1つ(1行1列)だけ返る。例:AVG(salary)。= や > と組み合わせる
・行副問合せ:1行(複数列)が返る。複数の列をまとめて比較するときに使う
・表副問合せ:複数行(表の形)が返る。IN や EXISTS と組み合わせて「○○のいずれかに一致するか」を判定する
上のツールの例はスカラ副問合せです。AVG(salary) が1つの値(平均給与)を返すので、外側で salary > (...) のように大小比較に使えます。複数の値が返るときは = ではなく IN や EXISTS を使う、という使い分けを覚えておきましょう。
副問合せは「内側から先に実行する」のが原則です。外側の条件は内側の結果が出るまで判定できないため、データベースは次の順で処理します。
・① 内側(副問合せ)を実行:結果(例では平均給与39)を確定させる
・② 結果を外側に差し込む:salary > 39 という形になる
・③ 外側を実行:差し込んだ値で行を絞り込む
身近な例で考えると、「先に基準(平均点)を計算してから、その基準で選ぶ」という当たり前の手順そのものです。なお外側の各行ごとに内側を繰り返し実行する「相関副問合せ」という形もありますが、まずは「内側が先」という基本の順序をしっかり押さえましょう。上のツールで内側→外側の流れを実際に追ってみてください。
ここまで解説してきた副問合せは「内側を1回だけ実行して値を確定させ、外側に渡す」形でした。これに対して、相関副問合せ(=外側の各行に対して内側を1回ずつ繰り返し実行する形)という応用形があります。
2つの違いを整理すると、次のようになります。
・通常の副問合せ:内側が1回だけ動く。外側からは独立していて、外側の値を参照しない
・相関副問合せ:外側の行を1行処理するたびに内側が動く。内側が「今処理中の外側の行の値」を参照する
身近な例で考えると、通常の副問合せは「クラス全体の平均を先に1回計算してから、全員と比べる」イメージ。相関副問合せは「生徒1人ひとりについて、その生徒のグループ内平均を別々に計算してから比べる」イメージです。まずは通常の「内側が先に1回動く」形を確実に理解したうえで、相関副問合せは「繰り返し版」として把握しておきましょう。
副問合せで複数の値が返ってくる場合(表副問合せ)は、= ではなく IN か EXISTS と組み合わせます。
・IN(=「いずれかと一致するか」):副問合せが返す値のリストの中に、比べたい値が含まれているかどうかを調べる
・EXISTS(=「行が存在するか」):副問合せの結果に1行でも行があれば真(=条件を満たす)とみなす
なぜ = ではなく IN を使うのか。= 39 は「1つの値と一致するか」を比べますが、副問合せが複数の行を返すと「どれと比べればよいか」が決まりません。IN は「リストの中のどれかと一致すればよい」という意味なので、複数の結果にも対応できます。たとえば「東京在住の社員ID一覧」を副問合せで取り出し、WHERE id IN (その一覧) と書くと「東京在住の社員の注文のみ」を絞り込めます。
まとめると:副問合せが1つの値を返す → = か > などで比較(スカラ副問合せ)、複数の値を返す → IN か EXISTS と組み合わせる(表副問合せ)という使い分けが基本です。