テーブルをつなぐ

INPUT · スライド

クエリの中にクエリ

01 / 05

2回に分けるのが面倒

「平均より多く買われた注文」を知りたいとする。いまのやり方だと2回クエリを書くことになるよね。

1回目で平均を出して、2回目でその数字を手で打ち込む。数字が変わるたびに書き直しになるし、途中でメモを間違えたら結果もおかしくなる。

SELECT AVG(quantity) FROM orders;

実行結果

3

02 / 05

カッコに入れて埋め込む

クエリの中に別のクエリをカッコで囲んで埋め込める。これをサブクエリ(内側のクエリ)と呼ぶよ。

手で打ち込んでいた 3 の場所に、(SELECT AVG(quantity) FROM orders) をそのまま置くだけ。数字を知らなくても書けるようになった。

SELECT * FROM orders  WHERE quantity > (    SELECT AVG(quantity) FROM orders  );

実行結果

2 | 3 | 2 | 4 | ウェブ
3 | 2 | 1 | 4 | 店頭
9 | 5 | 1 | 6 | 店頭

03 / 05

先に中が実行される

動く順番は内側から。まずカッコの中が実行されて1つの値になり、その値を使って外側が動くよ。

だから外側から見れば、サブクエリはただの値と同じ。= でも > でも < でも、いつもの比較演算子がそのまま使えるんだ。

SELECT * FROM orders  WHERE quantity = (    SELECT MAX(quantity) FROM orders  );

実行結果

9 | 5 | 1 | 6 | 店頭

04 / 05

中のクエリにも条件が書ける

サブクエリはふつうのクエリだから、WHERE を書いてもいい。「アプリ経由の平均より多い注文」のように、基準そのものを絞り込めるよ。

内側と外側で見ている表が同じでも問題ない。それぞれ別に実行されるだけだよ。

SELECT * FROM orders  WHERE quantity > (    SELECT AVG(quantity) FROM orders    WHERE channel = 'アプリ'  );

実行結果

2 | 3 | 2 | 4 | ウェブ
3 | 2 | 1 | 4 | 店頭
5 | 5 | 4 | 3 | ウェブ
8 | 2 | 2 | 3 | アプリ
9 | 5 | 1 | 6 | 店頭

05 / 05

返す値は1つにする

=> の右側に置くサブクエリは、1行1列を返すように書く。集計関数なら自然に1つになるけれど、そうでないときは ORDER BYLIMIT 1 で1行に絞ろう。

下は「いちばんまとめ買いされた注文の商品番号」を内側で求めて、その商品の注文だけを取り出しているよ。ここから書いてみよう。

SELECT * FROM orders  WHERE item_id = (    SELECT item_id FROM orders    ORDER BY quantity DESC    LIMIT 1  );

実行結果

5 | 5 | 4 | 3 | ウェブ
9 | 5 | 1 | 6 | 店頭