【さぶくえり】
サブクエリ(副問合せ) とは?
最終更新:
💡 SQLの中に入れ子で書く「もう一つのSELECT文」
SQLの中に入れ子で書かれたSELECT文のこと。外側のクエリの条件や値として内側のクエリの結果を利用でき、複雑な条件検索を1つのSQLで実現する。
📌 このページのポイント
サブクエリってどんなときに使うの?
たとえば「平均年齢より上のユーザーを取得する」ときだよ。SELECT * FROM users WHERE age > (SELECT AVG(age) FROM users) と書くと、内側のSELECTが返す平均を外側の条件に使える。図の仮データは30・40・50歳なので、平均40歳を超える50歳の人が該当するね。
内側が何行返してもいいの?
使い方によるよ。さっきの平均のように一つの値として使う「スカラーサブクエリ」は、1列で最大1行が必要なんだ。PostgreSQLでは複数行や複数列だとエラーになり、0行ならNULLになる。INやEXISTSは複数行の結果も扱えるよ。
INとEXISTSって何が違うの?
WHERE id IN (SELECT user_id FROM orders) は、idと同じ値が内側の結果にあるかを調べる。WHERE EXISTS (SELECT 1 FROM orders WHERE orders.user_id = users.id) は、そのユーザーに対応する注文の行が存在するかを調べるよ。大きさだけでどちらが速いと決めず、意味と実行計画を確認しよう。
JOINとサブクエリはどう使い分けるの?
相関サブクエリってなに?
外側の値を参照するサブクエリだよ。さっきのEXISTSで、orders.user_idと外側のusers.idを比べる部分がその例だね。論理的には外側の行に依存するけど、DBが条件に応じて結合などへ変換する場合もある。必ず行数分だけ同じ処理をするとは限らず、EXPLAINで計画を見て、実際の時間も測ることが大切だよ。
もっと詳しく知りたい人へ
NOT INで「該当しない行」を取るとき、NULLが混ざるとどうなる?
一致する値がなくても内側の結果にNULLがあると、NOT INの結果は真ではなくNULL(不明)になるため、WHERE条件ではその行が選ばれません。たとえば3 NOT IN (1, NULL)は真になりません。NULLを除外するのか、対応する行が存在しないことをNOT EXISTSで調べるのか、外側のNULLも含めて求める結果を決めてください。
📖 おまけ:英語の意味
「Subquery」 = 副(Sub)問合せ(Query)
💬 Subは「下位の」、Queryは「問合せ」。問合せの中に含まれる問合せという意味だよ