相関サブクエリ は、外部クエリ内にも現れるテーブルの参照を含むサブクエリです。例:
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
条項は FALSE
ですので、((5,6)
が
(5,7)
と同等ではない為)
このサブクエリ全体としては
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 (SELECTkey_val
FROMtbl_name
WHEREcorrelated_condition
)
そうでなければ、それらは役に立たず、スピードも遅くなりがちです。クエリを接合として書き換える事で、性能を向上させる事ができるかもしれません。
相関サブクエリは、外部クエリからの総計関数の結果を参照する事ができません。