スポンサーリンク

【応用情報技術者試験】メインクエリとサブクエリの違い

SQLと関係演算:抽出・結合・集計を整理 データベース

メインクエリは外側の問い合わせ、サブクエリ(副問い合わせ)はその中に含める問い合わせです。「何を取り出すか」を外側で書き、条件に使う平均値などを内側の問い合わせで求めると、複雑な条件を整理できます。

平均点より高い生徒を取り出す例

次の生徒表で、全体平均を超える生徒を抽出します。点数にはNULLがないものとします。

名前 スコア
Aさん 60
Bさん 80
Cさん 100
SELECT name, score
FROM students
WHERE score > (SELECT AVG(score) FROM students);

ここでは表名をstudents、列名をname・scoreとします。内側は平均80を求め、外側はscoreが80より大きいCさん(100点)を返す、と読むと分かりやすくなります。80点のBさんは「超える」条件には入りません。

「必ず内側から実行」は言い切らない

上の例は結果の意味を理解するための読み方です。実際の実行順はDBMSの最適化により変わることがあります。サブクエリが必ず先に一度だけ実行される、あるいは必ず遅い、とは限りません。

置く場所と返す結果を対応させる

場所・使い方 注意点
WHEREで値と比較 =や>の右側で単一値として使うなら、1列・最大1行のスカラ副問い合わせにする
WHEREでIN 一般的な単一列のINでは複数行の候補と照合できる
WHEREでEXISTS 条件に合う行が一つでもあるかを調べる
SELECTの式 単一値を返す副問い合わせを計算列として使える
FROM 問い合わせ結果を導出表として参照する。別名を付け、必要な列を選ぶ

利用できる構文や別名の要件はDBMSで確認します。スカラ副問い合わせが0行ならNULLになり、複数行を返すとエラーになります。

相関サブクエリは外側の列を参照する

SELECT s.name, s.score
FROM students AS s
WHERE s.score > (
  SELECT AVG(t.score)
  FROM students AS t
  WHERE t.class_id = s.class_id
);

この例ではclass_id列があり、各生徒が所属するクラスの平均を比較対象にしています。内側が外側のs.class_idを参照するため、相関サブクエリです。「クラスごとの平均と比較する」という意味と、実際に何回計算されるかは分けて考え、実行計画で確認します。

確認問題

「= (SELECT …)」の内側が2行を返しました。自動的にどちらか一方が選ばれますか?

解答・解説を見る

選ばれず、単一値を要求するスカラ副問い合わせでは複数行によるエラーになります。必要な条件に応じて集約で1行にするか、IN・EXISTSなどを検討します。

noteでサブクエリを他のSQLとつなげる

内側と外側の関係をつかんだら、SQL教材のSELECT・JOIN・GROUP BY・サブクエリをまとめて復習しましょう。単に書き方を覚えるだけでなく、返る行と列を追う練習につながります。

SQL頻出ポイントのnote教材を確認する

note教材ナビで他のテーマを選ぶ

参考資料

PostgreSQL公式:式とスカラ副問い合わせ(英語)

PostgreSQL公式:副問い合わせ式(英語)

この記事はSQLの説明です。WordPressなどのCMS内部で用いるメインクエリ・サブクエリという呼び方とは区別してください。

コメント