← Voltar para os artigos

Window functions: como agregar sem perder as linhas

Por Fernando Nagao Douverny · 08 de julho de 2026 · 2 min de leitura

intermediário

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 do GROUP 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.