Ты когда-нибудь задумывался, как Spotify понимает, что тебе надо поставить именно эту песню — ту, которую ты сам ещё не знал, что хочешь услышать?
Или как маркетплейс за долю секунды находит товары, которые купили люди с похожей историей заказов?
Там не магия. Там подзапрос.
Вопрос внутри вопроса
Обычный SQL-запрос — это как спросить у базы данных: «Дай мне всех пользователей из Москвы». Прямо и понятно.
Но реальные задачи устроены иначе. Алгоритм рекомендаций не спрашивает «дай всех», он спрашивает: «Дай мне тех пользователей, чьё поведение похоже на поведение тех, кто купил X, — но только среди активных за последние 30 дней, и исключи тех, кто уже видел эту рекомендацию».
Это — вложенная логика. И именно для неё существуют подзапросы.
Подзапрос — это запрос внутри запроса. Один SELECT живёт внутри другого SELECT. Результат внутреннего используется как условие или источник данных для внешнего.
Звучит просто. Работает — мощно.
Как это выглядит на практике
Представь: ты аналитик в финтех-стартапе. Тебе нужно найти клиентов, у которых есть транзакция на максимальную сумму за всё время — чтобы предложить им премиум-подписку.
Ты не знаешь заранее, какая сумма максимальная. Но ты можешь спросить у базы прямо в момент запроса:
SELECT name, amount
FROM customers
JOIN orders ON customers.id = orders.customer_id
WHERE amount = (
SELECT MAX(amount) FROM orders -- вот он, подзапрос
);
Внутренний запрос сначала находит максимум. Внешний — использует это число как фильтр. База данных делает всё за одно обращение. Никаких промежуточных таблиц, никакого ручного копирования значений.
Это и есть суть: логика становится вложенной — так же, как вложена логика любого умного алгоритма.
Когда одного уровня мало
Иногда нужно не просто отфильтровать, а сначала посчитать — потом отфильтровать из результата. Это другой уровень.
Подзапрос можно поместить не только в WHERE, но и в FROM — и тогда он становится временной таблицей, с которой дальше работает внешний запрос.
Представь аналитику в онлайн-игре: тебе нужно найти игроков, у которых максимальный рейтинг матча выше среднего по всему региону — чтобы направить их в более сложный дивизион.
SELECT player_id, max_rating
FROM (
SELECT player_id, MAX(match_rating) AS max_rating
FROM matches
GROUP BY player_id -- шаг первый: считаем для каждого
) AS player_stats
WHERE max_rating > (
SELECT AVG(match_rating) FROM matches -- шаг второй: фильтруем
);
Два уровня вложенности — два логических шага — один запрос. Это и называется думать запросами.
EXISTS: не «что», а «есть ли»
Есть ещё один инструмент, который многие недооценивают — EXISTS.
Он не вытаскивает данные. Он просто проверяет: существует ли хоть одна строка, удовлетворяющая условию?
Именно так работает логика антиспам-фильтров в мессенджерах. Не «покажи мне все сообщения с таким паттерном», а «проверь — есть ли у этого пользователя хоть одно сообщение, попадающее в стоп-лист». Если да — флаг.
SELECT name
FROM users AS u
WHERE EXISTS (
SELECT 1
FROM flagged_messages AS f
WHERE f.user_id = u.id
);
Быстро. Точно. Без лишних данных в памяти.
UNION: когда данные приходят из разных источников
Отдельная история — операции с множествами.
В реальных системах данные часто живут в разных таблицах с одинаковой структурой. Транзакции поступлений и транзакции расходов. Заказы из мобильного приложения и с веб-сайта. Контент, загруженный пользователями, и контент от брендов.
UNION объединяет результаты нескольких запросов в один список — и убирает дубликаты. UNION ALL делает то же самое, но дубликаты оставляет: он работает быстрее, когда ты уверен, что пересечений нет.
-- Все транзакции в одном списке — для единого отчёта
SELECT date, amount, 'доход' AS type FROM income
UNION ALL
SELECT date, amount, 'расход' AS type FROM expenses
ORDER BY date;
Именно такой запрос лежит в основе финансовых дашбордов стартапов: ты видишь единый поток событий, хотя данные физически хранятся в разных местах. Это и есть управление реальностью через запросы.
Почему это важно понять сейчас
Подзапросы — это не продвинутый синтаксис ради синтаксиса. Это способ думать.
Любой сложный алгоритм — рекомендательная система, антифрод, матчмейкинг, персонализация ленты в TikTok — в основе своей решает задачу: «Возьми подмножество из огромного множества, применив вложенные условия». SQL делает это буквально.
Аналитик данных, бэкенд-разработчик, ML-инженер — все они пишут запросы с подзапросами каждый день. Не потому что так принято, а потому что по-другому задача не решается.
Когда ты понимаешь, как работает вложенная логика в SQL — ты начинаешь по-другому читать архитектуру любого цифрового продукта. Видишь, где данные, как они связаны, что и откуда берётся.
Это не про таблички. Это про то, как устроен цифровой мир.
🔍 Хочешь копнуть глубже? Полный учебный материал с детальными примерами, схемами и крутыми иллюстрациями ждёт тебя на нашем сайте!