В предыдущих модулях мы научились извлекать данные из таблиц и соединять их. Однако иногда одного запроса недостаточно для получения нужного ответа. Вам может потребоваться сначала найти какое-то значение (например, среднее число или конкретный ID), а затем использовать это значение в другом запросе. Именно здесь на помощь приходят подзапросы.
Подзапрос (Subquery или внутренний запрос) - это оператор SELECT, вложенный в другой SQL-запрос. Запрос, содержащий подзапрос, называется внешним запросом (или основным запросом).
Подзапросы всегда заключаются в круглые скобки ().
Как правило, база данных сначала выполняет внутренний запрос. Результат этого внутреннего запроса затем передается во внешний запрос, который использует его для завершения своего выполнения.
-- Концептуальный пример
SELECT column_name
FROM table_name
WHERE column_name = (SELECT value FROM another_table);
^----- Сначала выполняется это -----^
Подзапросы часто классифицируют по типу данных, которые они возвращают:
FROM так, будто это временная таблица.Наиболее распространенное использование подзапроса - в предложении WHERE для фильтрации данных на основе динамического значения.
Сценарий: Найти фильмы, стоимость замены которых выше средней стоимости замены всех фильмов.
SELECT
title,
replacement_cost
FROM
film
WHERE
replacement_cost > (SELECT AVG(replacement_cost) FROM film);
Когда вы помещаете подзапрос в предложение FROM, он называется встроенным представлением (Inline View). Вы, по сути, создаете временную таблицу «на лету», которая существует только во время выполнения этого запроса.
Примечание: Вы обязательно должны дать встроенному представлению псевдоним (alias).
Сценарий: Получить список активных клиентов и соединить его с данными об их платежах.
SELECT
active_cust.first_name,
p.amount
FROM
(SELECT * FROM customer WHERE active = 1) AS active_cust
INNER JOIN
payment AS p ON active_cust.customer_id = p.customer_id;
В этом случае внешний запрос соединяет результат подзапроса (active_cust) с таблицей payment.
AVG или MAX) для фильтрации отдельных строк.NOT IN или NOT EXISTS.SELECT внутри другого запроса.WHERE или SELECT.FROM, требующие наличия псевдонима.