Предложение WHERE - это самое частое место, где можно встретить подзапрос. Оно позволяет фильтровать результирующий набор внешнего запроса на основе результатов внутреннего. В этом уроке мы изучим различные операторы, используемые с подзапросами в предложении WHERE.
Когда подзапрос возвращает одно единственное значение (скалярный подзапрос), вы можете использовать стандартные операторы сравнения, такие как =, <>, >, >=, < или <=.
Сценарий: Найти имена актеров, у которых такое же имя, как у актера с actor_id = 10.
SELECT
first_name,
last_name
FROM
actor
WHERE
first_name = (SELECT first_name FROM actor WHERE actor_id = 10)
AND actor_id <> 10;
Примечание: Если подзапрос вернет более одной строки, запрос завершится с ошибкой.
Если подзапрос возвращает несколько значений (один столбец, много строк), вы не можете использовать =, но можете использовать оператор IN.
Сценарий: Найти все фильмы, относящиеся к категории 'Action'.
Мы можем сделать это, сначала найдя category_id для 'Action', а затем отфильтровав таблицу film_category.
SELECT
title
FROM
film
WHERE
film_id IN (
SELECT film_id
FROM film_category
WHERE category_id = (SELECT category_id FROM category WHERE name = 'Action')
);
Примечание: В этом примере используется вложенный подзапрос внутри другого подзапроса!
Оператор NOT IN работает противоположным образом, исключая строки, которые совпадают с любым значением из списка.
Оператор EXISTS проверяет наличие хотя бы одной записи в подзапросе. Он часто эффективнее, чем IN для больших наборов данных, так как прекращает поиск, как только находит первое совпадение.
Сценарий: Найти всех клиентов, которые совершили хотя бы один платеж.
SELECT
c.first_name,
c.last_name
FROM
customer AS c
WHERE
EXISTS (
SELECT 1
FROM payment AS p
WHERE p.customer_id = c.customer_id
);
Подсказка: В EXISTS обычно пишут SELECT 1, так как фактически возвращаемые данные подзапроса не важны; важно лишь то, возвращаются ли строки вообще.
Сценарий: Найти фильмы, продолжительность которых больше, чем у любого фильма в категории 'Comedy'.
SELECT
title,
length
FROM
film
WHERE
length > ALL (
SELECT f.length
FROM film f
JOIN film_category fc ON f.film_id = fc.film_id
JOIN category c ON fc.category_id = c.category_id
WHERE c.name = 'Comedy'
);
=, >) только с подзапросами, возвращающими одно значение.WHERE делают ваш код динамичным и позволяют реализовывать многошаговую логику фильтрации.