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


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

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() 針對給定查詢的不同執行,可能會根據最佳化器選擇如何處理它而執行不同的次數。

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