Window functions: como agregar sem perder as linhas
Você quer, na mesma tabela, o valor de cada pedido e o total do cliente ao lado, para calcular quanto aquele pedido representa.
Com GROUP BY isso não sai. Ele resume — e ao resumir, joga as linhas originais fora.
O que o GROUP BY faz (e por que atrapalha aqui)
SELECT cliente, SUM(valor) AS total
FROM pedidos
GROUP BY cliente
Cinco pedidos de um cliente entram, uma linha sai. O detalhe do pedido acabou.
O que o OVER() muda
A mesma função de agregação, com OVER() no fim, para de resumir:
SELECT
cliente,
valor,
SUM(valor) OVER (PARTITION BY cliente) AS total_cliente
FROM pedidos
Cinco pedidos entram, cinco saem — cada um carregando o total do seu cliente. Agora dá para dividir um pelo outro:
SELECT
cliente,
valor,
valor / SUM(valor) OVER (PARTITION BY cliente) AS parte_do_total
FROM pedidos
Isso é o que uma window function faz: calcula olhando um conjunto de linhas vizinhas, mas responde linha a linha.
Lendo o OVER()
O que vai dentro dos parênteses define a “janela” — quais linhas entram na conta daquela linha:
PARTITION BY cliente— a conta recomeça a cada cliente. É o primo doGROUP BY, mas sem colapsar as linhas.ORDER BY data— dá ordem dentro da janela. É o que permite acumulado, média móvel e comparação com a linha anterior.OVER ()vazio — a janela é a tabela inteira.
SELECT
data,
valor,
SUM(valor) OVER (PARTITION BY cliente ORDER BY data) AS acumulado
FROM pedidos
Com ORDER BY dentro da janela, o SUM deixa de ser o total e vira o acumulado até aquela linha. É a mesma função — o que mudou foi a janela.
Pra lembrar
A regra prática é curta: precisa do total e do detalhe na mesma linha? Window function.
GROUP BY responde “quanto foi no total”. OVER() responde “quanto foi no total, e onde esta linha entra nesse total”. Quase toda pergunta de participação, ranking e evolução é da segunda família.