13.2.10.12 子查询限制

DELETE FROM t WHERE ... (SELECT ... FROM t ...);
UPDATE t ... WHERE col = (SELECT ... FROM t ...);
{INSERT|REPLACE} INTO t (SELECT ... FROM t ...);

exception:如果对修改后的 table 使用的是派生 table,并且该派生 table 已实现而不是合并到外部查询中,则上述禁止条件不适用。 (请参见第 8.2.2.4 节“通过合并或实现来优化派生 table 和视图引用”。)示例:

UPDATE t ... WHERE col = (SELECT * FROM (SELECT ... FROM t...) AS dt ...);

在这里,派生 table 的结果被实现为临时 table,因此在更新到t时,已经选择了t中的相关行。

换句话说,对于返回* n * -tuples 行的子查询,支持以下操作:

(expr_1, ..., expr_n) [NOT] IN table_subquery

但这不支持:

(expr_1, ..., expr_n) op {ALL|ANY|SOME} subquery

支持IN而不支持其他IN的行比较的原因是,通过将IN重写为=比较和AND操作的序列来实现。此方法不能用于ALLANYSOME

mysql> SELECT * FROM t1
       WHERE s1 IN (SELECT s2 FROM t2 ORDER BY s1 LIMIT 1);
ERROR 1235 (42000): This version of MySQL doesn't yet support
 'LIMIT & IN/ALL/ANY/SOME subquery'
SELECT ... WHERE x IN (SELECT f() ...);

此行为是对 SQL 标准的扩展。在 MySQL 中,它会产生不确定的结果,因为根据优化器选择的处理方式,对于给定查询的不同执行,f()可能执行不同的次数。

对于基于语句或混合格式的复制,这种不确定性的一个含义是,这样的查询可以在主服务器及其从属服务器上产生不同的结果。

首页