SQL Server: ROW_NUMBER()

🔍 O que é ROW_NUMBER()?

A função ROW_NUMBER() no SQL Server é uma função de janela que atribui um número sequencial a cada linha de um conjunto de resultados. O número é gerado com base na ordenação definida na cláusula ORDER BY e pode ser reiniciado para cada partição especificada em PARTITION BY.


🛠️ Como funciona?

A sintaxe básica é:

ROW_NUMBER() OVER (PARTITION BY coluna_partition ORDER BY coluna_order)

📌 Parâmetros:

  • PARTITION BY (opcional): Divide os dados em grupos. A numeração será reiniciada para cada partição.

  • ORDER BY (obrigatório): Define a ordem na qual os números serão atribuídos dentro de cada partição.


📊 Exemplo 1: Numerando registros dentro de um grupo

🎯 Cenário:

Temos uma tabela Vendas e queremos numerar as vendas de cada cliente, ordenando pelas datas das compras.

SELECT
    ClienteID,
    DataVenda,
    Valor,
    ROW_NUMBER() OVER (PARTITION BY ClienteID ORDER BY DataVenda) AS NumeroVenda
FROM Vendas;

📝 Resultado:

ClienteID
DataVenda
Valor
NumeroVenda
1
2024-01-01
500.00
1
1
2024-01-05
300.00
2
2
2024-01-02
700.00
1
2
2024-02-10
900.00
2

🔹 Explicação: Para cada ClienteID, a numeração começa em 1 e é incrementada conforme a DataVenda aumenta.


📊 Exemplo 2: Obtendo o primeiro registro de cada grupo

🎯 Cenário:

Queremos selecionar apenas a primeira venda de cada cliente.

WITH CTE_Vendas AS (
    SELECT
        ClienteID,
        DataVenda,
        Valor,
        ROW_NUMBER() OVER (PARTITION BY ClienteID ORDER BY DataVenda) AS NumeroVenda
    FROM Vendas
)
SELECT ClienteID, DataVenda, Valor
FROM CTE_Vendas
WHERE NumeroVenda = 1;

🔹 Explicação: Utilizamos uma CTE (Common Table Expression) para numerar as vendas e filtramos apenas as primeiras (NumeroVenda = 1).


🚀 Quando usar ROW_NUMBER()?

  • Para numeração sequencial de registros dentro de grupos.

  • Para filtrar registros duplicados, mantendo apenas um.

  • Para paginação de resultados (junto com OFFSET e FETCH).


⚠️ Cuidados ao utilizar ROW_NUMBER()

❌ Problema: Falta de PARTITION BY

Se PARTITION BY não for especificado, os números não reiniciam para cada grupo, gerando uma sequência única para toda a consulta.

SELECT ClienteID, DataVenda,
    ROW_NUMBER() OVER (ORDER BY DataVenda) AS NumeroVenda
FROM Vendas;

🔹 Aqui, a numeração será contínua para todos os clientes, sem reiniciar para cada um.

❌ Problema: Ordem não definida pode causar inconsistência

Como ROW_NUMBER() depende da cláusula ORDER BY, resultados podem ser inconsistentes se não houver um critério único de ordenação.

Solução: Adicionar um identificador único ao ORDER BY para evitar empates.

ORDER BY DataVenda, VendaID

✅ Conclusão

A função ROW_NUMBER() é uma ferramenta poderosa para organizar, filtrar e manipular dados dentro de conjuntos particionados. No entanto, é essencial definir corretamente PARTITION BY eORDER BY para garantir resultados precisos e previsíveis. 🚀

Data de Publicação: 16-02-2025

Categoria: SQL Server