CodeGym /コース /SQL SELF /ネストされたクエリって何?なんで必要なの?

ネストされたクエリって何?なんで必要なの?

SQL SELF
レベル 13 , レッスン 0
使用可能

じゃあ次のステップに進もうか — ネストされたクエリをSQLで使ってみよう。今日は、それが何なのか、なんで必要なのか、どんな種類があるのか、そして現実世界でどう役立つのかを見ていくよ。

ネストされたクエリ(またはサブクエリ)っていうのは、他のSQLクエリの中で使われるSQLクエリのこと。マトリョーシカとかキャベツみたいな感じ:外側のクエリがあって、その中にもう一つ小さいクエリが隠れてる。サブクエリが先に実行されて、その結果が外側のクエリ(たまに「メイン」って呼ばれる)で使われるんだ。

例で見てみよう:

例1: どうやって動くの?

例えば、studentsテーブルがあって、こんなデータが入ってるとする:

id 名前 年齢 グループ_id
1 アリサ 20 1
2 ボブ 22 2
3 クラーク 21 1
4 ディナ 23 3
5 エミリア 22 2

それから、グループの名前が入ってるgroupsテーブルもある:

id 名前
1 数学クラス
2 物理クラス
3 文学クラス

もし、学生が所属してるグループの名前を知りたいなら、ネストされたクエリを使えるよ:

SELECT 名前
FROM groups 
WHERE id IN (
    SELECT グループ_id 
    FROM students 
    WHERE 年齢 > 21
);

ここで何が起きてる?

ネストされたクエリ:

SELECT グループ_id 
FROM students 
WHERE 年齢 > 21

このクエリは、21歳より上の学生のグループ_idを全部選んでる。結果はグループIDのリスト、例えば[2, 3]みたいな感じ。

メインのクエリ:

SELECT 名前 
FROM groups 
WHERE id IN ([サブクエリの結果])

このクエリはサブクエリの結果を使って、idが2か3のグループの名前を返すよ。

結果:

物理クラス
文学クラス

まだよく分からない?まあ、当然だよね。でも心配しないで、今から全部説明するから!

まずシンプルなアイデアから始めよう — SELECTクエリの実行結果は、ある意味仮想テーブルなんだ。ちゃんとカラムもあるし、行もある。もうテーブルみたいなもんでしょ?

で、そのクエリの結果がテーブルなら、普通のテーブルと同じように使える。例えばJOINで使ったり、もっと複雑な構造でも使える。

ただし、名前がないのが問題。でも、カラムの式にも名前がないことあるし、それはalias(エイリアス)をつけて解決するよね。仮想テーブルにも同じことができる。

詳しくは次のレクチャーで — ネタバレはしないでおくね :P

ネストされたクエリの便利さ

  1. 複雑な課題をシンプルにできる。1つのテーブルだけじゃ欲しい情報が全部取れないこともある。サブクエリを使えば、まず中間結果を出して、それを使って最終データを取るって2段階に分けられる。

  2. 中間結果を扱える。ネストされたクエリは、データを処理する前に追加の計算が必要なときに便利。例えば最小値を探したり、合計を計算したり。

  3. コードの読みやすさアップ。ネストされたクエリを使うと、特に大きなテーブルや複雑なロジックのときにコードが整理されて分かりやすくなる。

ネストされたクエリの主なタイプ

ネストされたクエリは、SQLクエリのいろんな場所で使える。どこで使うかによって、いくつかのタイプに分かれるよ。

  1. SELECTの中のサブクエリ。カラムリストの中にサブクエリを書いて、を計算するのに使う。例えば、結果に新しいカラムを追加したいときに便利。

例 — 学生の中で最大年齢のカラムを追加してみよう:

SELECT 名前, 年齢,
       (SELECT MAX(年齢) FROM students) AS 最大_年齢 
FROM students;

結果:

名前 年齢 最大_年齢
アリサ 20 23
ボブ 22 23
クラーク 21 23
ディナ 23 23
エミリア 22 23
  1. FROMの中のサブクエリ。サブクエリを一時テーブルとして使う。まず集計や変換をしてから使いたいときに便利。

例 — 各グループごとの学生の平均年齢を計算してみよう:

SELECT tmp.グループ_id, tmp.平均_年齢
FROM (
    SELECT グループ_id, AVG(年齢) AS 平均_年齢
    FROM students
    GROUP BY グループ_id
) AS tmp -- 一時テーブルにtmpってエイリアスをつけてる 
WHERE tmp.平均_年齢 > 21;

結果:

グループ_id 平均_年齢
2 22.0
3 23.0
  1. WHEREHAVINGの中のサブクエリ。サブクエリを条件として使って、行をフィルタリングできる。よく使うのは、
  2. レコードの存在チェックや値の比較とか。

例 — 平均年齢より上の学生を探してみよう:

SELECT 名前, 年齢
FROM students
WHERE 年齢 > (
    SELECT AVG(年齢) 
    FROM students
);

結果:

名前 年齢
ボブ 22
ディナ 23
エミリア 22

ネストされたクエリを使うメリット

柔軟性アップ:ネストされたクエリを使うと、もっと複雑なデータ構造も扱えるようになる。

処理を段階的に分けられる:ロジックをサブクエリで分けることで、コードが読みやすくなる。

中間データにアクセスできる:データベースに一時テーブルを作らなくても、「その場で」データを処理できるよ。

コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION