Window functions permitem cálculos sobre conjuntos de linhas sem GROUP BY. Firebird suporta desde a versão 3.0.
ROW_NUMBER: numerar linhas
SELECT
nome,
valor,
ROW_NUMBER() OVER (ORDER BY valor DESC) AS posicao
FROM produtos;
RANK vs DENSE_RANK
SELECT
nome,
valor,
RANK() OVER (ORDER BY valor DESC) AS rank_com_gaps,
DENSE_RANK() OVER (ORDER BY valor DESC) AS rank_sem_gaps
FROM produtos;
- RANK: pula posições em caso de empate (1, 2, 2, 4)
- DENSE_RANK: sem gaps (1, 2, 2, 3)
PARTITION BY: ranking por grupo
-- Top 3 produtos mais vendidos por categoria
SELECT *
FROM (
SELECT
p.nome,
c.nome AS categoria,
SUM(v.quantidade) AS total_vendido,
ROW_NUMBER() OVER (PARTITION BY c.id ORDER BY SUM(v.quantidade) DESC) AS rn
FROM produtos p
JOIN categorias c ON c.id = p.categoria_id
JOIN vendas v ON v.produto_id = p.id
GROUP BY p.nome, c.nome, c.id
) t
WHERE rn <= 3;
Running total (soma acumulada)
SELECT
data_pedido,
valor,
SUM(valor) OVER (ORDER BY data_pedido) AS acumulado
FROM pedidos
ORDER BY data_pedido;
LAG e LEAD: comparar com linha anterior/seguinte
SELECT
mes,
total_vendas,
LAG(total_vendas, 1) OVER (ORDER BY mes) AS mes_anterior,
total_vendas - LAG(total_vendas, 1) OVER (ORDER BY mes) AS variacao
FROM vendas_mensais;
Armadilhas comuns
- Performance: window functions podem ser lentas em tabelas grandes. Use índices nas colunas de ORDER BY/PARTITION.
- Compatibilidade: só disponível no Firebird 3.0+. Verifique a versão do servidor.
- Sem índice: sem índice na coluna de ordenação, o Firebird faz sort em memória.
Precisa de queries com window functions? Descreva o cálculo em português no Sqlify e receba a query pronta com ROW_NUMBER, RANK ou LAG.
Conclusão
Window functions eliminam a necessidade de subqueries correlacionadas para rankings, totais acumulados e comparações temporais. São essenciais para relatórios e dashboards.