子查詢的限制html
● 一般,不能在子查詢中修改表並從同一表中進行選擇。例如,此限制適用於如下形式的語法:mysql
1. DELETE FROM t WHERE ... (SELECT ... FROM t ...); 2. UPDATE t ... WHERE col = (SELECT ... FROM t ...); 3. {INSERT|REPLACE} INTO t (SELECT ... FROM t ...);
例外狀況:若是使用的是派生表,而且派生表是物化的,而不是合併到外部查詢中,則上述禁止不適用。例子:sql
1. UPDATE t ... WHERE col = (SELECT * FROM (SELECT ... FROM t...) AS dt ...);
在這裏,來自派生表的結果被物化爲臨時表,所以在對 t 進行更新時,t 中的相關行已經被選中。ide
一般,能夠經過添加 NO_MERGE 優化器提示來影響優化器物化派生表。函數
● 僅部分支持行比較操做:優化
■ 對於 expr [NOT] IN subquery,expr 能夠是 n 元組(使用行構造函數語法指定),子查詢能夠返回 n 元組的行。所以,容許的語法更明確地表示爲 row_constructor [NOT] IN table_subqueryrest
■ 對於 expr op {ALL|ANY|SOME} subquery,expr 必須是標量值,子查詢必須是列子查詢;它不能返回多個列行。code
換句話說,對於返回多行 n 元組的子查詢,支持如下操做:htm
1. (expr_1, ..., expr_n) [NOT] IN table_subquery
但不支持如下查詢:get
1. (expr_1, ..., expr_n) op {ALL|ANY|SOME} subquery
支持 IN 的行比較而不支持其餘形式行比較的緣由是,IN 是經過將其重寫爲一序列 = 比較和 AND 操做來實現的。這種方法不適用於 ALL、ANY 或 SOME。
● 在 MySQL 8.0.14 以前,FROM 子句中的子查詢不能是關聯子查詢。在查詢執行期間,它們被總體物化(計算以生成結果集),所以不能按外部查詢的每行計算它們。優化器延遲物化直到須要結果,這可能容許避免物化。
● 對於某些子查詢運算符,MySQL 在 子查詢 中不支持使用 LIMIT:
1. mysql> SELECT * FROM t1 2. WHERE s1 IN (SELECT s2 FROM t2 ORDER BY s1 LIMIT 1); 3. ERROR 1235 (42000): This version of MySQL doesn't yet support 4. 'LIMIT & IN/ALL/ANY/SOME subquery'
● MySQL 容許子查詢引用存儲函數,該函數具備修改數據的反作用,例如向表中插入行。例如,若是 f() 插入行,則如下查詢能夠修改數據:
1. SELECT ... WHERE x IN (SELECT f() ...);
此行爲是 SQL 標準的擴展。在 MySQL 中,它能夠產生不肯定的結果,由於對於給定查詢的不一樣的執行,f() 可能會執行不一樣的次數,這取決於優化器選擇如何處理它。
對於基於語句或混合格式的複製,這種不肯定性的一個含義是,這樣的查詢可能在源及其從屬庫上生成不一樣的結果。
官方網址:
https://dev.mysql.com/doc/refman/8.0/en/subquery-restrictions.html