Подзапрос — это запрос, вложенный в другой запрос и используемый в WHERE, FROM, SELECT или с EXISTS. Он позволяет использовать результат одного запроса в другом, обеспечивая сложную фильтрацию и вычисления.
Подзапрос — это запрос, вложенный в другой запрос и используемый в WHERE, FROM, SELECT или с EXISTS. Он позволяет использовать результат одного запроса в другом, обеспечивая сложную фильтрацию и вычисления.
-- find users who have placed an order (their id is in the orders table)
SELECT name FROM users
WHERE id IN (SELECT user_id FROM orders); -- the subquery returns a list of user_ids
-- find products more expensive than the average
SELECT name, price FROM products
WHERE price > (SELECT AVG(price) FROM products); -- subquery returns a single value
Подзапрос в WHERE предоставляет значения для фильтрации — список (с IN) или одно значение (с операторами сравнения).
-- for each user, find those with above-average orders FOR THEIR COUNTRY
SELECT name FROM users u
WHERE order_count > (
SELECT AVG(order_count) FROM users
WHERE country = u.country -- references the OUTER query's row (correlated)
);
Коррелированный подзапрос ссылается на внешний запрос — он выполняется один раз для каждой строки внешнего запроса (потенциально медленнее). Некоррелированный подзапрос выполняется один раз.
-- users who have at least one order (often more efficient than IN)
SELECT name FROM users u
WHERE EXISTS (
SELECT 1 FROM orders o WHERE o.user_id = u.id -- just checks existence
);
EXISTS проверяет, возвращает ли подзапрос какие-либо строки — часто более эффективен, чем IN для проверок существования (может остановиться при первом совпадении).
-- use a subquery result as a table
SELECT country, avg_age FROM (
SELECT country, AVG(age) AS avg_age FROM users GROUP BY country
) AS country_stats
WHERE avg_age > 30;
Many subqueries can be rewritten as JOINs (often more efficient/readable).
WHERE id IN (SELECT ...) → can often be a JOIN
Use subqueries for clarity in filtering/aggregation; JOINs for combining data.
CTEs (WITH) are often a cleaner alternative to complex nested subqueries.
Подзапросы — важный метод SQL для сложного запрашивания — использование результата одного запроса в другом позволяет выполнять фильтрацию и вычисления, которые простые запросы не могут выразить, поэтому понимание их ценно для написания реальных запросов.
Знание форм — подзапросы в WHERE (фильтрация по списку с IN или одному значению с операторами сравнения), коррелированные подзапросы (ссылаются на внешний запрос, выполняются для каждой строки), EXISTS (эффективные проверки существования) и подзапросы в FROM (производные таблицы) — охватывает распространённые паттерны для выражения сложной логики.
Понимание различия между коррелированными и некоррелированными подзапросами важно для производительности (коррелированные подзапросы выполняются один раз для каждой строки внешнего запроса и могут быть медленными).
Одинаково ценно знание связи с JOINами и CTE: многие подзапросы можно переписать как JOINы (часто более эффективные и читаемые) или CTE (чище для сложных случаев), поэтому понимание, когда использовать каждый — подзапросы для ясности фильтрации/агрегации, JOINы для объединения данных — это практический навык.
Поскольку реальные запросы часто требуют вложений (фильтрация по агрегированным результатам, проверки существования, сравнение с вычисленными значениями) и поскольку понимание подзапросов, их характеристик производительности (особенно коррелированных), и их связи с JOINами/CTE важно для написания эффективных и результативных сложных запросов, овладение подзапросами — ценное и часто применяемое знание SQL за пределами базовых запросов и распространённая тема на собеседованиях, демонстрирующая способность выражать сложные требования к данным.