HexWolf Blog

SQL学習シリーズ⑥:サブクエリ

はじめに

前回JOIN句を紹介しました。これであらかた基本的な句は完了したので、個人的にはここから応用編になります。
アプローチであるサブクエリについて紹介します。

サブクエリはいつものクエリにさらにネストしてクエリを置きます。
やや抽象的ですが構文を読めば言っていることが分かります。

基本構文

書ける場所によっていくつか種類があるのが特徴です

WHERE句内で使う

SELECT name FROM users
WHERE user_id IN (SELECT user_id FROM orders WHERE price > 1000);

1000円以上の注文をしたuser_idの一覧を先にSELECTしてから、それに合致するusersを絞り込むという動きです。INだけでなく=EXISTSとも組み合わせられます。

FROM句内で使う

SELECT company, avg_price 
FROM 
  (
    SELECT company, AVG(price) AS avg_price FROM orders GROUP BY company
  ) AS company_avg WHERE avg_price > 500;

サブクエリの結果をまるごと1つのテーブルとして扱うパターンです。FROM句に書く場合は必ずASで名前をつける必要があります。

SELECT句内で使う

SELECT name, (SELECT COUNT(*) FROM orders WHERE orders.user_id = users.user_id) AS order_count
FROM users;

1行1値を返すサブクエリをそのままカラムのように差し込めます。
しかし後述する相関サブクエリという要件に入るため、件数次第では重くなるようです。

相関サブクエリ

サブクエリの中で外側のテーブルを参照しているものが相関サブクエリです。

これは外側の行1つ1つに対してサブクエリが実行されるイメージなので、対象件数が多いとその分だけ繰り返されるため処理は重いです。
一方で相関を持たないサブクエリは1回だけ実行されればいいので、書き方次第で速度の差がでそうです。

注意事項

  • FROM句のサブクエリには必ず別名(AS)をつける
  • 相関サブクエリは件数が多いテーブルに対して使うと遅くなりやすい
  • 複雑になりすぎる場合はJOINで書き直せないか検討する必要がある
  • ここ最近はウィンドウという機能もあるためそちらを利用するのも良いとのこと

次回はウィンドウについて触れようと思います。

とりあえず今日はこんな感じで