相関サブクエリと非相関サブクエリ
外側の行を参照する相関サブクエリ、その性能特性、そしてEXISTSがINより優れる場合を理解します。
「相関サブクエリと非相関サブクエリ」はCoddyKit上の無料SQL Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはSQL Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 SQL Academyコースには全4レッスンが含まれています。
非相関サブクエリ
非相関サブクエリは外側の行を参照しません。1回実行され、その結果が再利用されます:
SELECT * FROM users
WHERE id IN (
SELECT user_id FROM orders WHERE status = 'paid'
);相関サブクエリ
相関サブクエリは外側の行を参照します。論理的には外側の行ごとに再実行されます:
SELECT u.id, u.email
FROM users u
WHERE EXISTS (
SELECT 1 FROM orders o
WHERE o.user_id = u.id
AND o.total > 1000
);違いの見分け方
内側のSELECTが外側のFROMにある列を参照していれば、相関サブクエリです。
パフォーマンスへの影響
単純な相関サブクエリの計算量はO(outer × inner)です。現代的なプランナーは、これをセミ結合やハッシュ結合に書き換えることがよくあります。ただし、可能な場合はより単純な形式で記述すべきです。
EXISTSとIN
「少なくとも1つの一致」を確認する場合:
-- IN with non-correlated subquery (often the planner's favourite):
SELECT u.* FROM users u
WHERE u.id IN (SELECT user_id FROM orders);
-- EXISTS with correlated subquery (NULL-safe alternative):
SELECT u.* FROM users u
WHERE EXISTS (SELECT 1 FROM orders o WHERE o.user_id = u.id);NOT EXISTSは常にNOT INより優れている
内側の集合にNULLが含まれていると、NOT INは正しく動作しません。NOT EXISTSなら問題ありません。アンチ結合には常にNOT EXISTSを優先してください:
-- BUG-prone:
SELECT u.* FROM users u
WHERE u.id NOT IN (SELECT excluded_id FROM blocklist);
-- Safe:
SELECT u.* FROM users u
WHERE NOT EXISTS (SELECT 1 FROM blocklist b WHERE b.excluded_id = u.id);SELECT内の相関サブクエリ
「行ごとに検索する」パターンです:
SELECT u.id, u.email,
(SELECT MAX(created_at) FROM orders o WHERE o.user_id = u.id) AS last_order_at
FROM users u;
-- Often readable, but consider a LEFT JOIN + GROUP BY.UPDATE内の相関サブクエリ
行ごとに導出された値を取得します:
UPDATE products p
SET review_count = (
SELECT COUNT(*) FROM reviews r WHERE r.product_id = p.id
);LATERAL JOIN:より明確な相関パターン
「外側の行ごとにいくつかの行を検索する」場合、LATERALのほうが明確で高速なことがよくあります。詳しくは「高度なJOINパターン」で扱います。
サブクエリのキャッシュ
PostgreSQLはデフォルトでは、行をまたいでサブクエリの結果をキャッシュしません。同じ内側の結果が何度も必要な場合は、CTEを使います。
相関に使う列にインデックスを付ける
内側のサブクエリは、外側の行のキーでフィルタリングします。そのキーにインデックスがないと、外側の行ごとに全件スキャンが発生します。
-- For the orders example, this is essential:
CREATE INDEX orders_user_id_idx ON orders(user_id);まとめ
相関サブクエリは外側の行を参照します。
- EXISTSは代表的な相関形式です
- NOT INよりNOT EXISTSを優先します
- 相関に使う列にインデックスを付けます
- 多くの場合、LATERALのほうが明確な代替手段になります
クイックチェック
内部の集合にNULLが含まれる可能性がある場合、NOT EXISTSはなぜNOT INより安全なのでしょうか。
よくある質問
「相関サブクエリと非相関サブクエリ」レッスンは無料ですか?
はい。「相関サブクエリと非相関サブクエリ」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、SQL Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 SQL Academyコースには全4レッスンが含まれています。
「相関サブクエリと非相関サブクエリ」で何を学びますか?
外側の行を参照する相関サブクエリ、その性能特性、そしてEXISTSがINより優れる場合を理解します。 ブラウザで直接実行するハンズオンコードでSQL Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
SQL Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのSQL Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。
「相関サブクエリと非相関サブクエリ」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このSQL Academyレッスンでコードを書いて実行できますか?
はい。すべてのSQL Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- スカラー、行、テーブルのサブクエリ
- 相関サブクエリと非相関サブクエリ
- 共通テーブル式(WITH)
- 階層構造向け再帰CTE