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

AGROUP BY category ORDER BY revenue DESC LIMIT 3: ограничение по числу строк применится к каждой категории отдельно
BHAVING RANK() <= 3 поверх обычной агрегации с GROUP BY category и сортировкой выручки по убыванию
CDISTINCT ON (category) с ORDER BY category, revenue DESC LIMIT 3 для выбора трёх лучших товаров категории
DROW_NUMBER() OVER (PARTITION BY category ORDER BY revenue DESC) в подзапросе с фильтром по номеру <= 3
Правильный ответ. Паттерн «топ-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().

Можно заниматься бесплатно

Готовим вопросы…

Три вопроса по теме этой страницы, с объяснениями.

Продолжить в браузере

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