データベースの検索をする際に複数のテーブルを使ってデータを絞り込みたい場合が出てきます。
そのときに使えるのが副問い合わせとJOINです。
副問い合わせとJOINは似ていてJOINの方が簡単ですが、両方把握しておいたほうがいいです。
今回は副問い合わせについて解説します。
アホな僕の感覚ですが、ぶっちゃけ副問い合わせはめちゃくちゃ難しいです(笑)
副問い合わせとは
副問い合わせとは、簡単に言えばSELECT句の中にSELECT句を入れ子に出来るものです。
これで何がメリットかと言うと、別テーブルや同じテーブルの検索結果に基づいた検索を1つのSQL文で出来ることです。
1つのSQL文で出来ればその分パフォーマンスも良くなります。
副問い合わせはサブクエリとも呼ばれます。
まずは、クエリとはSELECTを実行して返ってきた結果と思って大丈夫です。
(本当は結果では無くて「こんなデータありますかー?」ってDBに問い合わせすることですけど、その結果のほうが僕はイメージしやすいかと思いました)
副問い合わせの構成
WHERE句での副問い合わせが一番使われるかなと個人的には思います。
WHERE句は「WHERE id = 値」のように指定したカラムに何の値が入っているかを指定しデータを絞り込みます。
その値の部分を別テーブル(または同じテーブル)の検索結果を使うものです。
具体的には以下のような形になります。
1 2 |
select カラムA1 from テーブルA where カラムA2 = (select カラムB1 from テーブルB); |
上の文では = で副問い合わせをしています。
イコールの場合は右辺の値が1つにならなければいけないので、副問い合わせのほうで1件に絞り込む条件(WHERE句)が必要になります。
副問い合わせの結果が複数になる場合は in を使って行います。
上記の例ではWHERE句の右辺で副問い合わせをしていますが、FROM句でも書くことが出来ます。
FROM句には「FROM テーブルA, テーブルB」のようにテーブルを複数指定することが出来ます。
このうち一つを副問い合わせにしてしまうという書き方です。
副問い合わせのサンプル
以下のようなテーブルを作成しました。
テーブルの作成の仕方についてはこちらの記事を参考にしてください。
ユーザーテーブル
id | user_name |
---|---|
1 | 田中 |
2 | 鈴木 |
3 | 山田 |
商品テーブル
id | product_name | price |
---|---|---|
1 | りんご | 100 |
2 | みかん | 50 |
3 | マンゴー | 120 |
購入履歴テーブル
id | user_id | product_id |
---|---|---|
1 | 3 | 1 |
2 | 3 | 3 |
3 | 1 | 2 |
このテーブルを使ってサンプルを作成していきます。
ある商品を購入したユーザーの名前を出力
例えば、ある商品を購入したユーザーの名前の一覧を出力したいとします。
まず、「ある商品を購入したユーザー」を考えます。
購入者ということは購入履歴の user_id が購入したユーザーのIDになります。
それを重複なく出力するために今回は GROUP BY を使ってみます。
1 2 |
select user_id from history GROUP BY user_id |
上記のコードを実行すると以下のようになります。
user_id |
---|
3 |
1 |
これで購入したユーザーのIDを入手できました。
次に上のユーザーIDに関連するユーザー名を取得します。
その場合、副問い合わせを使わない場合は以下のように書きます。
1 2 |
select user_name from user where id in (1, 3); |
実行すると以下のような結果が得られます。
user_name |
---|
田中 |
山田 |
2つ目のSQLの (1, 3) の部分に先に作成したSQLを入れ副問い合わせにすると以下のようになります。
1 2 3 4 |
select user_name from user where id in ( select user_id from history GROUP BY user_id); |
これで副問い合わせを使ったSQLが完成です。
簡単でしょ?
SQLを1本に出来るのですっきりしますね。
まとめ
副問い合わせはサブクエリともいう。
副問い合わせはクエリの中にクエリを入れ子にすること。
ここまで書きましたが僕もちゃんと理解出来ていないかもしれません・・・。
分かりやすい例が思い浮かばなかったです。
何か少しでも副問い合わせについて理解して頂けたら嬉しいです。
コメントを残す