相関サブクエリ は、外部クエリ内にも現れるテーブルの参照を含むサブクエリです。例:
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
は外部選択リストからもカラム名を探します。
特定の場合には、相関サブクエリは最適化されます。例:
valIN (SELECTkey_valFROMtbl_nameWHEREcorrelated_condition)
そうでなければ、それらは役に立たず、スピードも遅くなりがちです。クエリを接合として書き換える事で、性能を向上させる事ができるかもしれません。
相関サブクエリは、外部クエリからの総計関数の結果を参照する事ができません。
