相関サブクエリーは、外部クエリーにも現れるテーブルへの参照を含むサブクエリーです。例:
SELECT * FROM t1
WHERE column1 = ANY (SELECT column1 FROM t2
WHERE t2.column2 = t1.column2);
このサブクエリーには、サブクエリーの FROM
句でテーブル t1
が指定されていない場合でも、t1
のカラムへの参照が含まれます。そのため、MySQL はこのサブクエリーの外部を探し、外部クエリー内の t1
を見つけます。
テーブル t1
に column1 = 5
かつ column2 = 6
である行が含まれている一方、テーブル t2
に column1 = 5
かつ column2 = 7
である行が含まれているとします。単純な式 ... WHERE column1 = ANY (SELECT column1 FROM t2)
は TRUE
になりますが、この例では、サブクエリー内の WHERE
句は ((5,6)
が (5,7)
に等しくないため) FALSE
です。そのため、全体としての式は FALSE
です。
スコープルール: MySQL は、内部から外部に評価します。例:
SELECT column1 FROM t1 AS x
WHERE x.column1 = (SELECT column1 FROM t2 AS x
WHERE x.column1 = (SELECT column1 FROM t3
WHERE x.column2 = t3.column1));
このステートメントでは、SELECT column1 FROM t2 AS x ...
が t2
の名前を変更するため、x.column2
はテーブル t2
内のカラムである必要があります。SELECT column1 FROM t1 ...
がさらに外部にある外部クエリーであるため、これはテーブル t1
内のカラムではありません。
HAVING
または ORDER BY
句内のサブクエリーの場合、MySQL は外部選択リスト内でもカラム名を探します。
特定のケースでは、相関サブクエリーが最適化されます。例:
val IN (SELECT key_val FROM tbl_name WHERE correlated_condition)
そうしないと、これらは非効率的であり、遅くなる可能性があります。クエリーを結合として書き換えると、パフォーマンスが向上することがあります。
相関サブクエリー内の集約関数には、その関数に外部参照以外は何も含まれておらず、かつその関数が別の関数または式に含まれていない場合、外部参照を含めることができます。