01 / 05
2回に分けるのが面倒
「平均より多く買われた注文」を知りたいとする。いまのやり方だと2回クエリを書くことになるよね。
1回目で平均を出して、2回目でその数字を手で打ち込む。数字が変わるたびに書き直しになるし、途中でメモを間違えたら結果もおかしくなる。
SELECT AVG(quantity) FROM orders;実行結果
3
テーブルをつなぐ
INPUT · スライド
01 / 05
「平均より多く買われた注文」を知りたいとする。いまのやり方だと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つになるけれど、そうでないときは ORDER BY と LIMIT 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 | 店頭