Оглавление

14.2. Применение вложенных запросов в инструкции WHERE

Выведем имя пользователя, сделавшего заказ под номером 2, с помощью вложенного запроса:

SELECT `name` FROM `users_table`
WHERE `id_user` = (SELECT `id_user` FROM `orders_table`
WHERE `id_orders` = 2);
/* Выведет: Петров */


В данном примере мы объединили два запроса в один. Внутренний запрос  возвращает идентификатор пользователя, сделавшего заказ с номером 2, а внешний запрос по этому идентификатору получает имя пользователя. Как видно из примера, вложенный запрос всегда заключается в круглые скобки.
Уровень вложенности запроса может быть более двух. Однако на практике не используются запросы с уровнем вложенности более трех, так как это приводит к увеличению времени выполнения запроса.
Если вложенный запрос возвращает более одного значения, то MySQL генерирует ошибку. Обойти эту проблему можно следующими способами:


□ использовать ключевые слова IN или NOT IN:
 

 

SELECT `name` FROM `users_table`
WHERE `id_user` IN (SELECT `id_user` FROM `orders_table`);
Этот пример выведет
Иванов
Петров


□ использовать ключевые слова ANY или SOME:

SELECT `name` FROM `users_table`
WHERE `id_user` > ANY (SELECT `id_user` FROM `orders_table`);
/* Выведет: Петров */

 

□ использовать ключевое слово ALL:

SELECT `name` FROM `users_table`
WHERE `id_user` <= ALL (SELECT `id_user` FROM `orders_table`);
/* Выведет: Иванов */


При использовании ключевого слова IN проверяется совпадение с одним из значений, возвращаемых вложенным запросом. При использовании ключевого слова NOT IN, наоборот, проверяется отсутствие совпадения со списком значений. Если применяется ключевое слово ANY, то проверяемое значение поочередно сравнивается с каждым элементом, и если хотя бы одно сравнение возвращает значение Истина, то результат попадает в итоговую таблицу.

 
В случае использования ключевого слова ALL в результирующую таблицу попадут значения, только если все сравнения вернут значение Истина. С помощью ключевого слова EXISTS можно проверить, имеется ли хоть одна
строка в результирующей таблице. Если вложенный запрос дает непустой результат, то ключевое слово EXISTS возвращает 1 (истина). В противном случае возвращается значение 0 (ложь). Получить противоположные значения позволяет ключевое слово NOT EXISTS.

 
В качестве примера выведем всех клиентов, сделавших хотя бы один заказ.
Для наглядности добавим в таблицу users_table еще одного клиента:
INSERT INTO `users_table` VALUES (3, 'Сидоров');
Теперь выполним такой запрос:
SELECT `name` FROM `users_table`
WHERE EXISTS (SELECT * FROM `orders_table`
WHERE `orders_table`.`id_user` = `users_table`.`id_user`);
В результате мы получим:
Иванов
Петров

 
А теперь выведем клиентов, не сделавших ни одного заказа:
SELECT `name` FROM `users_table`
WHERE NOT EXISTS (SELECT * FROM `orders_table`
WHERE `orders_table`.`id_user` = `users_table`.`id_user`);

 

Этот запрос вернет
Сидоров

 
Обратите внимание, внутри вложенного запроса мы указываем поле таблицы users_table.id_user из внешнего запроса. Такая связь называется внешней ссылкой, а сам запрос называется коррелированным вложенным запросом.

Комментарии принадлежат их авторам. Мы не несем ответственности за их содержание.
Отправитель Нити