一般來說,您無法在子查詢中修改表格,同時從同一個表格中選取資料。例如,此限制適用於以下形式的語句
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()
可能會執行不同的次數。對於以語句為基礎或混合格式的複寫,此不確定性的一個含義是,此類查詢可能會在來源及其複本上產生不同的結果。