Estou construindo um endpoint de API para enviar dados estatísticos que serão plotados em um gráfico. A parte mais difícil é ser a consulta que preciso executar. Resumindo, quero os primeiros n
produtos mais vendidos por dia em um período. O período, por exemplo, pode ser qualquer intervalo de datas.
Suponha que eu tenha uma sales
tabela com os seguintes dados (este não é o esquema real que defini):
---------------------------------
date | product_name | count
---------------------------------
2015-01-08 | A | 10
2015-01-08 | B | 5
2015-01-08 | C | 1
2015-02-08 | A | 5
2015-02-08 | B | 3
2015-02-08 | C | 100
E suponha que eu queira os 2 produtos mais vendidos por dia. Eu quero uma consulta que retorne o seguinte:
---------------------------------
date | product_name | count
---------------------------------
2015-01-08 | A | 10
2015-01-08 | B | 5
2015-02-08 | C | 100
2015-02-08 | A | 5
Note que além de C
ser o produto mais vendido em todo o período, não aparece no top 2 do2015-01-08
Existe uma maneira de conseguir o que eu quero?
Obrigado :)
Uma maneira de resolver esses problemas é usar funções de janela:
Se houver empates, eles serão resolvidos arbitrariamente e apenas 2 linhas por data serão retornadas. Se você deseja resolver empates com uma preferência específica, pode alterar a ordem dentro da
OVER
cláusula. Digamos que você queira que os nomes dos produtos sejam classificados em ordem alfabética quando estiverem empatados nas principais vendas, use(... ORDER BY count DESC, product_name)
.Se você quiser todos os produtos (empatados) por data, basta alterar
ROW_NUMBER()
paraRANK()
.Outra forma de resolver é usando
JOIN LATERAL
. Isso provavelmente é mais rápido se você tiver índices ativados(date, count DESC)
e(date)
.