【SQL超入門講座】22.サブクエリ|SQLの中にSQLを書いて二段階抽出する方法

こんにちは、キノコードです。
SQLでデータ抽出を行う際に、一つのSQLの実行結果をもとに、また別のSQLで抽出を行いたい時がありませんか?
例えば、1年分の日別の売上データから、月ごとの売上の平均を求めたい場合を考えてみましょう。
このとき、まず日別の売上を月ごとに合計し、その上で月ごとの売上の平均を計算する必要があります。
このような2段階の集計が必要となる場合、一見すると2つのクエリが必要に感じます。
ではこれを1つのクエリで表現したい場合、どのようにすれば良いと思いますか?
今回解説するサブクエリを使えば、このような2段階以上の集計を1つのクエリで簡単に表現できます。
サブクエリが使えるようになると、SQLの表現の幅が広がりますので、ぜひマスターしてくださいね。
なおキノコードでは、この動画の他にもたくさんのプログラミングの動画を配信しています。
チャンネル登録がまだの方は、チャンネルがどこに行ったか分からなくならないように、是非チャンネル登録をお願いします。
それではレッスンスタートです。

レッスンで使ったファイルはこちら

キノクエストでアカウントの新規登録に進み、メール認証を完了します。

ログインした状態(プラン選択画面が表示されます)で下記のボタンをクリックいただくか、ファイルダウンロードページのURL:https://kinoquest.jp/main/file_download/を直接アドレスバーに入力ください。

サブクエリについて

サブクエリは、ひとつのSQLをカッコで括ったもので、一つ のテーブルとして扱えるようになります。
そして別のSQL文の内部に埋め込んで使用することができます。

例えば抽出や計算をしたAというSQLがあるとします。
Aを更に計算したり、別のテーブルとくっつけたりしたいことがありますよね。
このような時、Aをカッコで括りサブクエリとして、別のSQLに埋め込んで使用します。
サブクエリには様々な使い方がありますが、ちょっといくつか例文を見てみましょう。

SELECT カラムA
 ,SUM(カラムB<integer>)
FROM

(SELECT カラムA
 ,カラムB<integer>
FROM テーブル
WHERE 条件式)

GROUP BY カラムA

このSQL内部のサブクエリは、テーブルからAというカラムとBという数値が入ったカラムを条件式によって抽出しています。
それをFROM句に用いることで、カラムAごとの数値の合計を計算しています。

次の例文も見てみましょう。

SELECT テーブルC.カラムA
 ,テーブルC.カラムB
 ,テーブルD.カラムE
FROM

(SELECT カラムA
 ,カラムB
FROM テーブルC
WHERE 条件式)

JOIN テーブルD
ON テーブルC.カラムA = テーブルD.カラムA

こちらはちょっと複雑ですが、サブクエリでテーブルCからカラムAとBを抽出しています。
これをテーブルDと結合し、テーブルCのカラムAとB、テーブルDのカラムEを抽出しています。

それでは、ここからは実際にテーブルを使ってSQLを書いてみましょう。
使用するtest_tableは、このようなカラムからなる、いつ誰が何をどれだけ売り上げたか記録されているテーブルです。

サブクエリを使ってみよう

まずはtest_tableから、
「売上日」ごとに「商品分類がトップスの商品を売り上げたユニークな社員ID」の数を計算します。
そこから月ごとにのべ何人の人がトップスを売り上げたのか計算してみます。

SQLはこのように書きます。

SELECT SUBSTRING(TO_CHAR("売上日",'YYYY-MM-DD'),1,7) ym,
 SUM(uu) nb_uu
FROM
(SELECT "売上日",
 COUNT(DISTINCT "社員ID") uu
FROM test_table
WHERE "商品分類" = 'トップス'
GROUP BY "売上日") tmp
GROUP BY ym

まず、サブクエリの中を見てみてみましょう。
「売上日」ごとに「商品分類がトップスの商品を売り上げたユニークな社員ID」の数がここで抽出・計算されています。
確認のため、一度サブクエリだけを切り取って実行してみましょう。
売上日ごとにユニークな社員IDの数が抽出されました。

このサブクエリをテーブルとしてFROM句に使用し、月ごとにのべ何人の人がトップスを売り上げたのかを計算します。
サブクエリの売上日のカラムからsubstr関数で年月の部分だけを抽出し、ユニークな社員IDの数をSUM関数で月ごとに集計すればOKです。

次は別のテーブルtest01とtest02を使って抽出を行ってみたいと思います。
test01はtest02はそれぞれこのようなカラムからなるテーブルです。
それでは「数学」が3以下の人の「国語」がいくつなのかを確認してみましょう。

SELECT test01.氏名,
 test01.出席番号,
 数学,
 国語
FROM

(SELECT *
FROM test01
WHERE 数学 <= 3) test01

JOIN test02
on test01.出席番号 = test02.出席番号

こちらも、まずサブクエリの中を見てみましょう。
サブクエリでは、test01のテーブルから、「数学」が3以下の人を抽出してきています。
このサブクエリに、test02のテーブルを、どちらのテーブルにもある出席番号で結合しています。
そして氏名、出席番号、数学、国語のカラムを一緒に抽出しています。

このようにSQLの中でサブクエリを作れば、複雑な条件で抽出を行えるようになります。
以上が、サブクエリの数例となります。

終わりの挨拶

今回のレッスンは以上です。
サブクエリの使い方はご理解いただけましたでしょうか。
キノコードでは、これからも色々なSQLについての動画を出していこうと思っています。
気に入っていただけましたら、ぜひチャンネル登録をお願いします!
それではまた次のレッスンでお会いしましょう。