#### 13.2.11.12 对子查询的限制

[](<>)[](<>)

-   通常，您不能在子查询中修改表并从同一个表中进行选择。例如，此限制适用于以下形式的陈述：

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

    例外：如果对修改后的表使用派生表并且该派生表被具体化而不是合并到外部查询中，则上述禁令不适用。（看[第 8.2.2.4 节，“通过合并或实现优化派生表、视图引用和公用表表达式”](derived-table-optimization.html)。） 例子：

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

    这里派生表的结果被物化为临时表，因此`吨`在更新到时已经被选中`吨`发生。

    通常，您可以通过添加[`NO_MERGE`](optimizer-hints.html#optimizer-hints-table-level)优化器提示。看[第 8.9.3 节，“优化器提示”](optimizer-hints.html).

-   仅部分支持行比较操作：

    -   为了`*`表达式`* [不] 在 *`子查询`*`,*`表达式`*可以是一个*`n`*-tuple（使用行构造函数语法指定）并且子查询可以返回*`n`*-元组。因此，允许的语法更具体地表示为`*`row_constructor`* [不] 在 *`表子查询`*`

    -   为了`*`表达式`* *`操作`* {全部|任何|一些} *`子查询`*`,*`表达式`*必须是标量值且子查询必须是列子查询；它不能返回多列行。

        换句话说，对于返回行的子查询*`n`*-元组，这是支持的：

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

    但这不受支持：

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

    支持行比较的原因`在`但不是为了其他人`在`是通过将其重写为一个序列来实现的[`=`](comparison-operators.html#operator_equal)比较和[`和`](logical-operators.html#operator_and)操作。这种方法不能用于`全部`,`任何`， 要么`一些`.

-   在 MySQL 8.0.14 之前，子查询`从`子句不能是相关的子查询。它们在查询执行期间被整体具体化（评估以产生结果集），因此不能按外部查询的每行评估它们。优化器延迟实现直到需要结果，这样可以避免实现。看[第 8.2.2.4 节，“通过合并或实现优化派生表、视图引用和公用表表达式”](derived-table-optimization.html).

-   MySQL 不支持`限制`在某些子查询运算符的子查询中：

    ```
    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'
    ```

    看[第 13.2.11.10 节，“子查询错误”](subquery-errors.html).

-   MySQL 允许子查询引用具有数据修改副作用的存储函数，例如将行插入表中。例如，如果`F（）`插入行，以下查询可以修改数据：

    ```
    SELECT ... WHERE x IN (SELECT f() ...);
    ```

    此行为是对 SQL 标准的扩展。在 MySQL 中，它会产生不确定的结果，因为`F（）`对于给定查询的不同执行，可能会执行不同的次数，具体取决于优化器选择处理它的方式。

    对于基于语句或混合格式的复制，这种不确定性的一个含义是这样的查询可以在源及其副本上产生不同的结果。
