SQLを使ってデータベースを扱っているとサブクエリ (副問合わせともいう) を使うような機会があります。
サブクエリ自体は難しくありませんが、初心者にとってはつまづきやすいポイントなのでこの記事で紹介していきたいと思います。
サブクエリとは
サブクエリとは簡単にいうとSQL文の中にSQL文を書くことです。
例えば、以下のような書き方を言います。
SELECT カラム①
FROM テーブル①
WHERE カラム② = (SELECT カラム名
FROM テーブル②
WHERE カラム名 = 値)
まずカッコ内のSQL文を実行し、テーブル②からWHERE句の条件に当てはまる値を取得してきます。(この値を仮に値①と名付けます)
それから、外側のSQL文を実行しテーブル①からWHERE句の条件に当てはまる値(カラム②と値①が一致するカラム①の値)を取得します。
サブクエリは覚えてしまえば便利ですが動作が重くなるというデメリットがあります。
そのため、基本的にはサブクエリを使わない方法で実装し他に選択肢がない場合のみ使うというほうが良いと思います。
実装
それでは、実際にサブクエリを使ってみましょう。
以下のようなusersテーブルとscoresテーブルがあったとします。 (以下の例の場合、サブクエリを使う必要はありませんがあえて使用しています)
<usersテーブル>
id | name | age | gender |
1 | 太郎 | 20 | male |
2 | 花子 | 26 | female |
3 | 一郎 | 32 | male |
<scoresテーブル>
user_id | japanese | math | english |
1 | 62 | 90 | 85 |
2 | 78 | 82 | 77 |
3 | 69 | 98 | 82 |
この2つのテーブルから年齢が25歳以上の人の数学の点数を取得したい場合、サブクエリを使ってどのようなSQL文を書けば良いでしょうか。(usersテーブルのidとscoresテーブルのuser_idは一致しています)
正解がこちらです。
SELECT math
FROM scores
WHERE user_id IN (SELECT id
FROM users
WHERE age >= 25)
「WHERE カラム名 IN 値」で値が複数ある場合にも対応できます。
覚えておきましょう。
では、次にuserそれぞれの名前と国語の平均値を取得するSQLをサブクエリを使って作ってみてください。(平均値は「AVG(カラム名)」で取得できます)
正解がこちらです。
SELECT name,
(SELECT AVG(japanese) FROM scores) as jp_avg
FROM users
上記の2つの例でもあげたようにサブクエリの2つ目のSQL文はSELECT、WHERE、FROMなどさまざまな場所で使えます。
まとめ
サブクエリは使うタイミングがあまり多くありませんが、使わないと他に手段がないという場合もあります。
基本を押さえていざという時のために覚えておきましょう。