Spec-Zone.ru › MariaDB

Ограничения подзапросов



Ниже обсуждаются ряд ограничений, касающихся подзапросов.

В следующих примерах будут использованы следующие таблицы и данные:


CREATE TABLE staff(name VARCHAR(10),age TINYINT);

CREATE TABLE customer(name VARCHAR(10),age TINYINT);
INSERT INTO staff VALUES 
('Bilhah',37), ('Valerius',61), ('Maia',25);

INSERT INTO customer VALUES 
('Thanasis',48), ('Valerius',61), ('Brion',51);

ORDER BY и LIMIT

Для использования ORDER BY или ограничения LIMIT в подзапросах оба должны быть использованы. Например:

SELECT * FROM staff WHERE name IN (SELECT name FROM customer ORDER BY name);
+----------+------+
| name     | age  |
+----------+------+
| Valerius |   61 |
+----------+------+

является допустимым, но

SELECT * FROM staff WHERE name IN (SELECT NAME FROM customer ORDER BY name LIMIT 1);
ERROR 1235 (42000): This version of MariaDB doesn't 
  yet support 'LIMIT & IN/ALL/ANY/SOME subquery'

нет.

Изменение и выбор из одной таблицы в подзапросе

Невозможно одновременно изменять и выбирать данные из одной таблицы в подзапросе. Например:

DELETE FROM staff WHERE name = (SELECT name FROM staff WHERE age=61);
ERROR 1093 (HY000): Table 'staff' is specified twice, both 
  as a target for 'DELETE' and as a separate source for data

Операции сравнения строк

Частичная поддержка операций сравнения строк. Выражение в

expr op {ALL|ANY|SOME} subquery,

должно быть скалярным, а подзапрос может возвращать только один столбец.

Однако, из-за того, как IN реализован (он переписывается как последовательность = сравнений и AND), выражение в

expression [NOT] IN subquery

разрешается быть n-кортежем, а подзапрос может возвращать строки из n-кортежей.

Например:

SELECT * FROM staff WHERE (name,age) NOT IN (
  SELECT name,age FROM customer WHERE age >=51]
);
+--------+------+
| name   | age  |
+--------+------+
| Bilhah |   37 |
| Maia   |   25 |
+--------+------+

допускается, но

SELECT * FROM staff WHERE (name,age) = ALL (
  SELECT name,age FROM customer WHERE age >=51
);
ERROR 1241 (21000): Operand should contain 1 column(s)

нет.

Связанные подзапросы

Подзапросы в операторе FROM не могут быть связанными подзапросами. Они не могут быть оценены для каждой строки внешнего запроса, так как они оцениваются для получения набора результатов во время выполнения запроса.

Сохраненные функции

Подзапрос может ссылаться на сохранённую функцию, которая изменяет данные. Это расширение стандарта SQL, но может привести к неопределённым результатам. Например, рассмотрим:

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

где f() вставляет строки. Функция f() может быть выполнена разное количество раз в зависимости от того, как оптимизатор обрабатывает запрос.

Поэтому такой конструкт небезопасен для использования в репликации, которая не является строчно-ориентированной, так как на мастер-сервере и на сервере-слепке могут быть получены разные результаты.

Содержимое, воспроизведённое на этом сайте, является собственностью соответствующих владельцев, и это содержимое не предварительно проверяется MariaDB. Мнения, информация и мнения, выраженные в этом содержании, не обязательно отражают позицию MariaDB или любой другой стороны.

© 2023 MariaDB
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.
https://mariadb.com/kb/en/subquery-limitations/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API