Window Functions em SQL — O Hack Secreto que Faz Você Virar Sênior Se você trabalha com dados e ainda não domina Window Functions, sua carreira está andando em câmera lenta. Window Functions parecem mágica no começo: Mas a verdade é simpler do que parece. E uma vez que você entende, você não volta mais ao SQL antigo. Este post desmente o mito: Window Functions não é complicado. É apenas algo que ninguém explica direito. O Problema que Window Functions Resolvem Digamos que você tem uma tabela de vendas: | id | produto | categoria | vendedor | valor | |----|---------|-----------|----------|-------| | 1 | A | Eletrônicos | João | 5000 | | 2 | B | Eletrônicos | Maria | 4500 | | 3 | C | Livros | João | 500 | | 4 | D | Livros | Ana | 800 | | 5 | E | Eletrônicos | João | 6000 | Pergunta: quais são os TOP 2 produtos DENTRO DE CADA CATEGORIA? Sem Window Functions, você faz assim: Complicado? SIM. Lento? MUITO. Legível? NUNCA. Com Window Functions: Mais limpo. Mais rápido. Mais fácil de entender. A Sintaxe: Partes da Window Function Toda Window Function segue este padrão: Vamos quebrar: FUNCAO() — o que você quer calcular: — número da linha dentro do grupo (1, 2, 3...) — rank com empate (1, 2, 2, 4...) — rank sem pular números (1, 2, 2, 3...) — valor da linha anterior — valor da próxima linha , , — funções agregadas com contexto OVER — marca que é Window Function PARTITION BY coluna — agrupa por essa coluna > "Calcule isso DENTRO DE CADA grupo" Se omitir PARTITION BY, calcula sobre TODA a tabela. ORDER BY coluna — ordena DENTRO de cada grupo > Importante para ROW_NUMBER, RANK, LAG, LEAD Exemplos Práticos (Do Fácil ao Avançado) Exemplo 1: Ranking Simples Quer o TOP 3 produtos por vendas, em cada categoria: Resultado: | categoria | produto | valor | rank | |-----------|---------|-------|------| | Eletrônicos | E | 6000 | 1 | | Eletrônicos | A | 5000 | 2 | | Eletrônicos | B | 4500 | 3 | | Livros | D | 800 | 1 | | Livros | C | 500 | 2 | O que acontece aqui: 1. — agrupa dados por categoria 2. — ordena cada grupo por valor (maior primeiro) 3. — numera as linhas dentro de cada grupo Sem Window Function, isso era 10 linhas de subquery. Aqui é 1 linha clara. Exemplo 2: Comparar com Linha Anterior Seu chefe quer saber: qual foi o crescimento de vendas semana a semana? Resultado: | semana | total_vendas | vendas_semana_anterior | crescimento_absoluto | crescimento_pct | |--------|------|--------|--------|--------| | 31 | 50000 | NULL | NULL | NULL | | 32 | 52000 | 50000 | 2000 | 4.00 | | 33 | 48500 | 52000 | -3500 | -6.73 | | 34 | 55000 | 48500 | 6500 | 13.40 | pega o valor da linha anterior, dentro da ordem definida. Sem LAG, você precisa de self-join (traumático). Exemplo 3: Acumulativo (Running Total) Seu gestor quer saber quanto você vendeu acumulado até cada semana: Resultado: | semana | total_vendas | vendas_acumuladas | |--------|------|--------| | 31 | 50000 | 50000 | | 32 | 52000 | 102000 | | 33 | 48500 | 150500 | | 34 | 55000 | 205500 | significa: > "Some desde a primeira linha até a linha atual" Sem isso, SUM() agrega tudo. Com isso, agrega progressivamente. Exemplo 4: Percentual do Total Cada vendedor quer saber qual % de cada categoria ele vendeu: Resultado: | vendedor | categoria | valor | total_categoria | pct_do_total | |----------|-----------|-------|---|---| | João | Eletrônicos | 6000 | 15500 | 38.71 | | Maria | Eletrônicos | 4500 | 15500 | 29.03 | | Ana | Eletrônicos | 5000 | 15500 | 32.26 | | Ana | Livros | 800 | 1300 | 61.54 | | João | Livros | 500 | 1300 | 38.46 | Aqui você tem: Total por categoria (calculado com ) Percentual de cada linha em relação ao seu grupo Exemplo 5: Diferença Entre Linhas (Detecção de Mudança) Você quer identificar quando o status de uma campanha mudou de uma semana para a outra: Resultado: | semana | campanha | status | status_anterior | detectou_mudanca | |--------|----------|--------|---|---| | 1 | Black Friday | Ativa | NULL | Não | | 2 | Black Friday | Ativa | Ativa | Não | | 3 | Black Friday | Pausada | Ativa | SIM - MUDANÇA DETECTADA | | 4 | Black Friday | Pausada | Pausada | Não | Perfeito para detectar anomalias automaticamente. A Diferença de Performance Window Functions não é só elegância. É velocidade real. Teste com dataset de 50 milhões de linhas: Sem Window Function (Subquery aninhada): Tempo: 45 segundos (banco tem que rodar subquery para CADA linha) Com Window Function: Tempo: 2 segundos (passo único, otimizado) Speedup: 22x mais rápido Não é marketing. É ciência de banco de dados. Onde Window Functions BRILHAM ✓ Ranking e Top-N: "Top 3 produtos por categoria" ✓ Comparação temporal: "Mês a mês", "semana a semana" ✓ Acumulativos: "Vendas acumuladas até agora" ✓ Percentuais: "% do total" ✓ Detecção de mudança: "Quando o status mudou?" ✓ Médias móveis: "Média de 7 dias" ✗ Onde evitar: Quando você precisa filtrar antes de calcular (use WHERE + GROUP BY) A Curva de Aprendizado Dia 1: "Isso é confuso, prefir