Learnly
SQL для аналитиков/Глава 8/Урок 1

Подзапросы: запрос внутри запроса

Подзапросы: запрос внутри запроса

Подзапрос, это SELECT внутри другого SELECT. Это позволяет использовать результат одного запроса в другом.

Зачем нужны подзапросы

Иногда условие фильтрации, не фиксированное число, а результат другого запроса:

-- Пользователи старше СРЕДНЕГО возраста
-- Среднее заранее не знаем, оно в базе
SELECT name, age
FROM users
WHERE age > (SELECT AVG(age) FROM users);

Подзапрос (SELECT AVG(age) FROM users) выполняется первым, возвращает одно число, которое используется в WHERE.

Подзапрос в WHERE

-- Клиенты, сделавшие хотя бы один заказ
SELECT name, email
FROM customers
WHERE id IN (
    SELECT DISTINCT customer_id
    FROM orders
    WHERE status = 'completed'
);

-- Клиенты без заказов
SELECT name
FROM customers
WHERE id NOT IN (
    SELECT DISTINCT customer_id
    FROM orders
    WHERE customer_id IS NOT NULL
);

Подзапрос в FROM

Результат подзапроса можно использовать как таблицу:

SELECT city, ROUND(AVG(avg_check), 0) AS city_avg
FROM (
    SELECT
        c.city,
        AVG(o.amount) AS avg_check
    FROM orders o
    JOIN customers c ON o.customer_id = c.id
    GROUP BY c.id, c.city
) AS customer_stats
GROUP BY city
ORDER BY city_avg DESC;

Когда подзапросы становятся нечитаемыми

Вложенные подзапросы быстро становятся сложными:

SELECT * FROM (
    SELECT * FROM (
        SELECT * FROM orders WHERE ...
    ) t1 WHERE ...
) t2 WHERE ...

Для таких случаев существует лучший инструмент, CTE.

💡 Главная мысль: Подзапрос, запрос внутри запроса. Полезен когда условие, это результат другого запроса. Для сложной логики лучше использовать CTE.