13.2.10.12 Ограничения на подзапросы
-
В общем случае, вы не можете изменять таблицу и одновременно выбирать из той же таблицы в подзапросе. Например, это ограничение применяется к операторам следующих форм:
DELETE FROM t WHERE ... (SELECT ... FROM t ...); UPDATE t ... WHERE col = (SELECT ... FROM t ...); {INSERT|REPLACE} INTO t (SELECT ... FROM t ...);Исключение: это ограничение не применяется, если для изменяемой таблицы используется производная таблица, и эта производная таблица материализуется, а не объединяется с внешним запросом. (См. раздел 8.2.2.4, «Оптимизация производных таблиц и ссылок на представления с помощью объединения или материализации».) Пример:
UPDATE t ... WHERE col = (SELECT * FROM (SELECT ... FROM t...) AS dt ...);
Здесь результат из производной таблицы материализуется как временная таблица, поэтому соответствующие строки в
tуже были выбраны к моменту обновленияt. -
Операции сравнения строк частично поддерживаются:
Для
,expr[NOT] INsubqueryexprможет бытьn-кортежем (указанным с помощью синтаксиса конструктора строк), а подзапрос может возвращать строкиn-кортежей. Поэтому допустимый синтаксис более точно выражается какrow_constructor[NOT] INtable_subqueryДля
,exprop{ALL|ANY|SOME}subqueryexprдолжно быть скалярным значением, а подзапрос должен быть подзапросом столбца; он не может возвращать строки с несколькими столбцами.
Другими словами, для подзапроса, возвращающего строки
n-кортежей, поддерживается следующее:(
expr_1, ...,expr_n) [NOT] INtable_subqueryНо это не поддерживается:
(
expr_1, ...,expr_n)op{ALL|ANY|SOME}subqueryПричина, по которой поддерживаются сравнения строк для
IN, но не для других, заключается в том, чтоINреализуется путем переписывания его как последовательности сравнений=и операцийAND. Этот подход нельзя использовать дляALL,ANYилиSOME. Подзапросы в предложении
FROMне могут быть связанными подзапросами. Они материализуются целиком (вычисляются для получения набора результатов) во время выполнения запроса, поэтому они не могут быть вычислены для каждой строки внешнего запроса. Оптимизатор откладывает материализацию до тех пор, пока результат не потребуется, что может позволить избежать материализации. См. раздел 8.2.2.4, «Оптимизация производных таблиц и ссылок на представления с помощью объединения или материализации».-
MySQL не поддерживает
LIMITв подзапросах для определенных операторов подзапроса:mysql>
SELECT * FROM t1WHERE s1 IN (SELECT s2 FROM t2 ORDER BY s1 LIMIT 1);ERROR 1235 (42000): This version of MySQL does not yet support 'LIMIT & IN/ALL/ANY/SOME subquery' -
MySQL разрешает подзапросу ссылаться на хранимую функцию, которая имеет побочные эффекты изменения данных, такие как вставка строк в таблицу. Например, если
f()вставляет строки, следующий запрос может изменять данные:SELECT ... WHERE x IN (SELECT f() ...);
Это поведение является расширением стандарта SQL. В MySQL это может привести к недетерминированным результатам, поскольку
f()может быть выполнен разное количество раз для разных выполнений данного запроса в зависимости от того, как оптимизатор решит его обработать.Для репликации на основе операторов или смешанной репликации одним из последствий этой недетерминированности является то, что такой запрос может давать разные результаты на источнике и его репликах.
© 2025 Oracle
Licensed under the GPLv2 License.