子查询限制
通常,您不能修改表并在子查询中从同一表中选择。例如,此限制适用于以下形式的语句:
DELETE FROM tWHERE ... (SELECT ...FROM t ...);UPDATE t ...WHERE col = (SELECT ...FROM t ...); {INSERT |REPLACE }INTO t (SELECT ...FROM t ...);例外:如果对修改后的表使用的是派生表,并且该派生表已实现而不是合并到外部查询中,则上述禁止条件不适用。(请参见“通过合并或实现来优化派生表,视图引用和公用表表达式”。)示例:
UPDATE t ...WHERE col = (SELECT *FROM (SELECT ...FROM t...)AS dt ...);在这里,派生表的结果被实现为临时表,因此
t
在进行更新时已经选择了其中的相关行t
。通常,您可以通过添加
NO_MERGE
优化器提示来影响优化器以实现派生表。请参见“优化器提示”。仅部分支持行比较操作:
- 对于,可以是-tuple(使用行构造函数语法指定),并且子查询可以返回-tuples的行。因此,允许的语法更具体地表示为
expr[NOT] IN subquery
expr
n
n
row_constructor[NOT] IN table_subquery
- 对于,必须是标量值,并且子查询必须是列子查询;它不能返回多列行。
exprop{ALL|ANY|SOME}subquery
expr
换句话说,对于返回
n
-tuples 行的子查询,支持以下操作:(expr_1, ..., expr_n) [NOT]
IN table_subquery但这不被支持:
(expr_1, ..., expr_n) op {
ALL |ANY |SOME } subquery支持
IN
但不支持其他行比较的原因IN
是通过将其重写为一系列=
比较和AND
操作来实现的。这种方法不能用于ALL
,ANY
或SOME
。- 对于,可以是-tuple(使用行构造函数语法指定),并且子查询可以返回-tuples的行。因此,允许的语法更具体地表示为
- 在MySQL 8.0.14之前,
FROM
子句中的子查询不能为关联子查询。它们在查询执行期间整体实现(评估为生成结果集),因此无法对外部查询的每一行进行评估。优化程序将延迟实现,直到需要结果为止,这可以避免实现。请参见“通过合并或实现来优化派生表,视图引用和公用表表达式”。 MySQL
LIMIT
在某些子查询运算符的子查询中不支持:mysql>
SELECT *FROM t1WHERE s1IN (SELECT s2FROM t2ORDER BY s1LIMIT 1); ERROR 1235 (42000): This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'请参见“子查询错误”。
MySQL允许子查询引用具有数据修改副作用(例如在表中插入行)的存储函数。例如,如果
f()
插入行,则以下查询可以修改数据:SELECT ...WHERE xIN (SELECT f() ...);此行为是对SQL标准的扩展。在MySQL中,它可能会产生不确定的结果,因为
f()
根据优化程序选择的处理方式,给定查询的不同执行可能会执行不同的次数。对于基于语句或混合格式的复制,这种不确定性的一个暗示是,这样的查询可以在主服务器及其从属服务器上产生不同的结果。