一般而言,您無法在子查詢中修改表格,並同時從同一表格中選取。例如,此限制適用於以下形式的陳述式:
DELETE FROM t WHERE ... (SELECT ... FROM t ...); UPDATE t ... WHERE col = (SELECT ... FROM t ...); {INSERT|REPLACE} INTO t (SELECT ... FROM t ...);
例外:如果針對修改後的表格您使用的是衍生表格,且該衍生表格是實體化而不是合併到外部查詢中,則上述禁止事項不適用。(請參閱第 10.2.2.4 節,「使用合併或實體化來最佳化衍生表格、檢視參考和通用表格運算式」)。範例
UPDATE t ... WHERE col = (SELECT * FROM (SELECT ... FROM t...) AS dt ...);
在這裡,衍生表格的結果會被實體化為臨時表格,因此在對
t
進行更新時,t
中的相關列已經被選取了。一般而言,您可能可以透過新增
NO_MERGE
最佳化器提示來影響最佳化器將衍生表格實體化。請參閱第 10.9.3 節,「最佳化器提示」。列比較運算僅部分支援
對於
,expr
[NOT] INsubquery
expr
可以是一個n
元組(使用列建構子語法指定),而子查詢可以傳回n
元組的列。因此,允許的語法更具體地表示為row_constructor
[NOT] INtable_subquery
對於
,expr
op
{ALL|ANY|SOME}subquery
expr
必須是一個純量值,而子查詢必須是一個欄子查詢;它不能傳回多欄列。
換句話說,對於傳回
n
元組列的子查詢,這是支援的(expr_1, ..., expr_n) [NOT] IN table_subquery
但是這是不支援的
(expr_1, ..., expr_n) op {ALL|ANY|SOME} subquery
支援
IN
的列比較而不支援其他列比較的原因是,IN
是透過將其重寫為=
比較和AND
運算的序列來實作的。這種方法不能用於ALL
、ANY
或SOME
。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()
針對給定查詢的不同執行,可能會根據最佳化器選擇如何處理它而執行不同的次數。對於基於語句或混合格式的複寫,這種不確定性的一個含義是,這樣的查詢可能會在來源及其複本上產生不同的結果。