相关子查询是包含对也出现在外部查询中的表的引用的子查询 。例如:
SELECT * FROM t1
WHERE column1 = ANY (SELECT column1 FROM t2
WHERE t2.column2 = t1.column2);
请注意,子查询包含对列的引用
t1
,即使子查询的
FROM
子句未提及表
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));
在此语句中,x.column2
必须是表中的列,t2
因为SELECT column1
FROM t2 AS x ...
重命名t2
。它不是表中的列,t1
因为
它是一个更远SELECT column1 FROM t1 ...
的外部查询。
对于HAVING
orORDER
BY
子句中的子查询,MySQL 还会在外部选择列表中查找列名。
对于某些情况,优化了相关子查询。例如:
val IN (SELECT key_val FROM tbl_name WHERE correlated_condition)
否则,它们效率低下并且可能很慢。将查询重写为连接可能会提高性能。
相关子查询中的聚合函数可能包含外部引用,前提是该函数只包含外部引用,并且该函数不包含在另一个函数或表达式中。