• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • 子查询限制

    • 通常,您不能修改表并在子查询中从同一表中选择。例如,此限制适用于以下形式的语句:

      DELETE FROM t WHERE ... (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 subqueryexprnnrow_constructor[NOT] IN table_subquery
      • 对于,必须是标量值,并且子查询必须是列子查询;它不能返回多列行。exprop{ALL|ANY|SOME}subqueryexpr

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

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

      但这不被支持:

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

      支持IN但不支持其他行比较的原因IN是通过将其重写为一系列=比较和AND操作来实现的。这种方法不能用于ALLANYSOME

    • 在MySQL 8.0.14之前,FROM子句中的子查询不能为关联子查询。它们在查询执行期间整体实现(评估为生成结果集),因此无法对外部查询的每一行进行评估。优化程序将延迟实现,直到需要结果为止,这可以避免实现。请参见“通过合并或实现来优化派生表,视图引用和公用表表达式”。
    • MySQL LIMIT在某些子查询运算符的子查询中不支持:

      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'
      

      请参见“子查询错误”。

    • MySQL允许子查询引用具有数据修改副作用(例如在表中插入行)的存储函数。例如,如果f()插入行,则以下查询可以修改数据:

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

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

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

    上篇:优化子查询