13.2.10.6 Подзапросы с EXISTS или NOT EXISTS
Если подзапрос возвращает хотя бы одну строку, то EXISTS
является subqueryTRUE, а NOT EXISTS
является subqueryFALSE. Например:
SELECT column1 FROM t1 WHERE EXISTS (SELECT * FROM t2);
Традиционно, подзапрос с EXISTS начинается с SELECT *, но он может начинаться с SELECT 5 или SELECT column1 или с чего угодно. MySQL игнорирует список SELECT в таком подзапросе, поэтому это не имеет значения.
Для предыдущего примера, если t2 содержит какие-либо строки, даже строки, содержащие только NULL значения, то условие EXISTS является TRUE. Это на самом деле маловероятный пример, потому что подзапрос с [NOT] EXISTS почти всегда содержит корреляции. Вот некоторые более реалистичные примеры:
-
Какой тип магазина присутствует в одном или нескольких городах?
SELECT DISTINCT store_type FROM stores WHERE EXISTS (SELECT * FROM cities_stores WHERE cities_stores.store_type = stores.store_type); -
Какой тип магазина присутствует ни в одном городе?
SELECT DISTINCT store_type FROM stores WHERE NOT EXISTS (SELECT * FROM cities_stores WHERE cities_stores.store_type = stores.store_type); -
Какой тип магазина присутствует во всех городах?
SELECT DISTINCT store_type FROM stores WHERE NOT EXISTS ( SELECT * FROM cities WHERE NOT EXISTS ( SELECT * FROM cities_stores WHERE cities_stores.city = cities.city AND cities_stores.store_type = stores.store_type));
Последний пример — подзапрос NOT
EXISTS с двойным вложением. То есть, он содержит условное выражение NOT
EXISTS внутри условного выражения NOT EXISTS. В формальном смысле, он отвечает на вопрос “существует ли город с магазином, который не находится в Stores”? Но проще сказать, что вложенный подзапрос NOT EXISTS отвечает на вопрос “является ли x TRUE для всех y?”
© 2025 Oracle
Licensed under the GPLv2 License.