SQLの副問い合わせ(サブクエリ)について聞いたことがない、もしくは使ったことがないという方が意外にも多いようです。SQLの副問い合わせを扱えるようになると、よりフレキシブルなデータベースの扱いが可能となりますので、エンジニアとしては必須の知識であると言えます。
今回の記事では、SQLの副問い合わせの概要について分かりやすく解説をしつつ、SQLの副問い合わせの種類とそれぞれの使い方を説明していきましょう。
- SQLの副問い合わせの概要
- SQLの副問い合わせの種類と使い方
SQLの副問い合わせとは
SQLの副問い合わせ(サブクエリ)とは、SQLステートメントの内部に入れ子状態で入っているSQL文(クエリ)のことです。言葉だけでは分かりにくいかと思いますので、実際にSQLの副問い合わせを使用したSQL文を見てみましょう。
まず、前提として以下のようなテーブルがあるとします。
staffsテーブル
+------+--------+ | id | name | +------+--------+ | 1 | Kenji | | 2 | Tom | | 3 | Bob | | 4 | Suzuki| | 5 | Robin | +------+--------+
rollsテーブル
+------+--------+ | id | roll | +------+--------+ | 1 | ご飯係 | | 2 | ご飯係 | | 3 | 掃除係 | | 4 | 掃除係 | | 5 | 班長 | +------+---------+
ここで、ご飯係のスタッフの名前を取得したいとしましょう。その場合、サブクエリを用いることで簡単に取得することができます。
SELECT * FROM staffs WHERE EXISTS ( SELECT * FROM rolls WHERE staffs.id = rolls.id AND rolls.roll = "ご飯係");
上記の例文は、「staffsテーブルからrollsテーブル内でidが一致し、rollが「ご飯係」のnameカラムを出力する。」という意味のSQL文です。サブクエリはWHERE以降のSELECT文です。
SQLの副問い合わせを使用しない場合には、以下のように
SELECT * FROM staffs
「staffsテーブルからデータを出力する。」という単純なクエリしか書くことができませんでした。SQLの副問い合わせを使用すれば、指定する条件の範囲でデータベースからデータを取得することが可能なのです。
【関連記事】
▶︎SQL select文のサンプル集 結合、ソート、別テーブル生成の記述方法は?
▶︎【実例で学ぶ】SQL「UPDATE」文の使い方 基礎・応用編
▶︎【初心者向け】SQLのDELETE文の使い方を現役SE目線で解説
SQLの副問い合わせの種類と使い方
さて、こちらではSQLの副問い合わせの種類と使い方についてご紹介をしていきましょう。たくさんの使い方がありますので一度で覚えようとせず、まずは構造と出力される結果への理解を深めるようにしましょう。
使用するテーブル
まずは、こちらで共通して使用するテーブルを確認しましょう。
staffsテーブル
+------+-------+-------+ | id | name | age | +------+-------+-------+ | 1 | Bob | 28 | | 2 | Taka | 25 | | 3 | Tom | 28 | | 4 | Robin | 45 | | 5 | Suzu | 45 | +------+-------+-------+
jobsテーブル
+------+---------+ | id | roll | +------+---------+ | 1 | rice | | 2 | cury | | 3 | desert | +------+---------+
rollsテーブル
+--------+----------+ | jobid | staffid | +--------+----------+ | 1 | 1 | | 2 | 2 | | 3 | 3 | | 1 | 4 | | 2 | 5 | +--------+----------+
WHERE句内で使用する副問い合せ1
まずはSQLのWHERE句の中で副問い合わせを使用してみましょう。
SELECT * FROM staffs WHERE EXISTS ( SELECT * FROM staffs WHERE staffs.age > 28);
以下が出力結果です。
+------+--------+--------+ | id | name | age | +------+--------+--------+ | 4 | Robin | 45 | | 5 | Suzu | 45 | +------+---------+--------+
こちらのSQL文は、「staffsテーブルからageが28以上(28歳は含まない)のレコードを取得する」という意味です。単純な指定のため副問い合わせを使用する意味を感じにくいかもしれませんが、次に紹介する例などは副問い合わせの効果をより存分に感じることができます。
WHERE句内で使用する副問い合せ2
同じくSQLのWHERE句の中で副問い合わせを使用してみましょう。
SELECT DISTINCT jobid FROM rolls WHERE staffid IN (SELECT id FROM staffs WHERE age = 45);
以下が出力結果です。
+------+ |jobid | +------+ | 1 | | 2 | +------+
こちらのSQL文は、「rollsテーブルからstaffidカラムを参照し、ageが45のstaffのjobidを表示する」という意味になります。
実際にstaffsテーブルのageカラムで45歳のstaff(idが4と5のレコード)は、rollsテーブルでjobidが1と2と振られていることがわかります。
FROM句内で使用する副問い合せ
次にSQLのFROM句の中で副問い合わせを使用してみましょう。
SELECT age, count FROM (SELECT age, COUNT(age) as count FROM staffs GROUP BY age) as ageLists;
以下が出力結果です。
+------+--------+ | age | count | +------+--------+ | 45 | 2 | | 28 | 2 | | 25 | 1 | +------+--------+
複雑なSQL文でしたが、「staffsテーブルからageカラムを参照し、降順で年齢ごとの人数をcountカラムに登録する」という意味になります。
実際にstaffsテーブルのageカラムを見てみると、45歳のstaffが2人、28歳のstaffが2人、25歳のstaffが1人いることがわかりますね。
まとめ
今回の記事では、SQLの副問い合わせの概要について分かりやすく解説をしつつ、SQLの副問い合わせの種類とそれぞれの使い方を説明していきました。SQLの副問い合わせを理解すれば、さらにデータベースをフレキシブルに扱えるようになるはずです。
今回の記事ではSQLの副問い合わせの概要をご紹介していきましたので、さらに深くSQLコマンドなどについても学んでみてくださいね。
【関連記事】
▶︎SQLの達人への第一歩、結合と抽出を同時に処理するINNER JOINの使い方をマスターしよう
▶︎SQL having 集約関数の絞り込み whereよりもレスポンスが遅い理由とは?
▶︎SQLで重複データを扱うサンプルコード集 カウント、集計、最新のみ抽出、重複禁止
SQLステートメントという用語が出てきました。これは、SQL文の最初の「SELECT」「DELETE」「INSERT」「UPDATE」の4種類の宣言のことです。
ステートメント(Statement)という英語自体に「宣言」という意味があります。SQL文を扱う上で、知っておきたい用語の1つです。