Нужно получить топ-3 продукта по выручке внутри каждой категории. Какой подход корректен в PostgreSQL?

AНаписать GROUP BY category ORDER BY revenue DESC LIMIT 3 — лимит применится внутри каждой группы
BДобавить HAVING RANK() <= 3 к обычному GROUP BY-запросу с сортировкой
CИспользовать DISTINCT ON (category) с ORDER BY category, revenue DESC LIMIT 3
DИспользовать ROW_NUMBER() OVER (PARTITION BY category ORDER BY revenue DESC) в подзапросе, затем отфильтровать по номеру строки
Правильный ответ. Паттерн «топ-N внутри группы» требует оконной функции ROW_NUMBER() OVER (PARTITION BY ...) с последующей фильтрацией по номеру строки во внешнем запросе.

Разбор

LIMIT без оконной функции ограничивает весь результат запроса, а не каждую группу отдельно. DISTINCT ON (category) даёт только топ-1. HAVING не знает о позиции строки внутри группы. Правильный подход: в CTE или подзапросе присвоить ROW_NUMBER() OVER (PARTITION BY category ORDER BY revenue DESC) AS rn, затем во внешнем запросе написать WHERE rn <= 3. При ничьих можно использовать RANK() вместо ROW_NUMBER().

Проверь себя · 1/3разбор после ответа
Нужно получить количество заказов по паре (user_id, status) из таблицы orders. Какой запрос верный?
Тренировать SQL в Telegram

Ещё вопросы по теме «Агрегация, GROUP BY и HAVING»