Вывести менеджеров, которые продали больше 500000 рублей за месяц одним запросом
Что проверяют
Для фронтенд-разработчика это проверка базовой грамотности в данных: знаете ли вы GROUP BY и HAVING и понимаете ли, почему такие вещи считает база, а не браузер. Особенно часто вопрос звучит в fullstack-вакансиях с Node.js. Следом уточняют: а если «за месяц» значит «в любом из месяцев»?
Как отвечать
Сначала спросите, имеется в виду конкретный месяц или любой. Для конкретного, при таблицах managers(id, name) и sales(manager_id, amount, sold_at):
SELECT m.id, m.name, SUM(s.amount) AS total
FROM managers m
JOIN sales s ON s.manager_id = m.id
WHERE s.sold_at >= DATE '2026-08-01'
AND s.sold_at < DATE '2026-09-01'
GROUP BY m.id, m.name
HAVING SUM(s.amount) > 500000;Проговорите логику:
- WHERE: отсекает строки до группировки, здесь это фильтр по периоду;
- GROUP BY: собирает продажи каждого менеджера в одну группу;
- HAVING: фильтрует готовые группы, поэтому условие на
SUMпишется здесь; - полуоткрытый интервал:
>=начала и<начала следующего месяца не теряет последний день и позволяет использовать индекс поsold_at.
Для варианта «в любом месяце» группируйте ещё по date_trunc('month', s.sold_at) (PostgreSQL) и сверху берите DISTINCT по менеджеру. Скажите и про тип: деньги хранят в numeric, а не во float.
Мостик к своей специальности: выгрузить все продажи на клиент и посчитать через reduce можно, но это тащит по сети тысячи строк ради пары имён. Агрегация живёт на сервере, фронтенд получает готовый список.
Где спотыкаются
Пишут WHERE SUM(amount) > 500000. Агрегат в WHERE недопустим, база вернёт ошибку.
Фильтруют через EXTRACT(MONTH FROM sold_at) = 8. Так смешивается август всех лет, а функция над колонкой не даёт использовать обычный индекс.
Пишут BETWEEN '2026-08-01' AND '2026-08-31' по колонке timestamp. Продажи 31 августа после полуночи в выборку не попадут.