0Pricing
SQL Academy · レッスン

相関サブクエリと非相関サブクエリ

外側の行を参照する相関サブクエリ、その性能特性、そして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フィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. スカラー、行、テーブルのサブクエリ
  2. 相関サブクエリと非相関サブクエリ
  3. 共通テーブル式(WITH)
  4. 階層構造向け再帰CTE
← SQL Academyに戻る