文件首頁
MySQL 8.4 參考手冊
相關文件 下載本手冊
PDF (美式信紙) - 39.9Mb
PDF (A4) - 40.0Mb
Man Pages (TGZ) - 258.5Kb
Man Pages (Zip) - 365.5Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 8.4 參考手冊  /  ...  /  子查詢的限制

15.2.15.12 子查詢的限制

  • 一般來說,您無法在子查詢中修改表格,同時從同一個表格中選取資料。例如,此限制適用於以下形式的語句

    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] IN subqueryexpr 可以是 n 元組(使用列建構子語法指定),而子查詢可以傳回 n 元組的列。因此,允許的語法更具體地表示為 row_constructor [NOT] IN table_subquery

    • 對於 expr op {ALL|ANY|SOME} subqueryexpr 必須是純量值,而子查詢必須是欄子查詢;它不能傳回多欄列。

    換句話說,對於傳回 n 元組列的子查詢,支援此項

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

    但不支援此項

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

    支援針對 IN 的列比較,但不支援其他運算的原因是,IN 是透過將其重寫為 = 比較和 AND 運算的序列來實作。此方法不能用於 ALLANYSOME

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

    請參閱第 15.2.15.10 節,「子查詢錯誤」

  • MySQL 允許子查詢參照具有資料修改副作用(例如將列插入表格)的儲存函式。例如,如果 f() 插入列,則以下查詢可以修改資料

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

    此行為是 SQL 標準的延伸。在 MySQL 中,它可能會產生不確定性的結果,因為對於給定查詢的不同執行,根據最佳化器選擇如何處理它,f() 可能會執行不同的次數。

    對於以語句為基礎或混合格式的複寫,此不確定性的一個含義是,此類查詢可能會在來源及其複本上產生不同的結果。