13.2.10.7 相关子查询
相关子查询是包含对 table 的引用的子查询,该 table 也出现在外部查询中。例如:
SELECT * FROM t1
WHERE column1 = ANY (SELECT column1 FROM t2
WHERE t2.column2 = t1.column2);
请注意,即使子查询的FROM
子句未提及 tablet1
,子查询也包含对t1
列的引用。因此,MySQL 查找子查询之外的内容,并在外部查询中找到t1
。
假设 tablet1
包含其中column1 = 5
和column2 = 6
的行;同时,tablet2
包含一行column1 = 5
和column2 = 7
。简单 table 达式... WHERE column1 = ANY (SELECT column1 FROM t2)
将是TRUE
,但是在此示例中,子查询中的WHERE
子句是FALSE
(因为(5,6)
不等于(5,7)
),因此整个 table 达式是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
必须是 tablet2
中的列,因为SELECT column1 FROM t2 AS x ...
重命名了t2
。它不是 tablet1
中的列,因为SELECT column1 FROM t1 ...
是更远的外部查询。
对于HAVING
或ORDER BY
子句中的子查询,MySQL 还在外部选择列 table 中查找列名。
对于某些情况,优化了相关子查询。例如:
val IN (SELECT key_val FROM tbl_name WHERE correlated_condition)
否则,它们效率低下并且可能会变慢。将查询重写为联接可能会提高性能。
相关子查询中的聚合函数可以包含外部引用,前提是该函数只包含外部引用,并且该函数未包含在另一个函数或 table 达式中。