0Pricing
SQL Interview Prep · Aula

ROW_NUMBER para sequenciamento exclusivo

Atribua um número de linha determinístico dentro de cada partição.

ROW_NUMBER para sequenciamento exclusivo é uma aula grátis de SQL Interview Prep no CoddyKit. Esta é a aula 2 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de SQL Interview Prep, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de SQL Interview Prep inclui 4 aulas no total.

O que ROW_NUMBER garante

ROW_NUMBER() atribui um inteiro único e sem lacunas a cada linha dentro da sua partição, começando em 1 e seguindo o ORDER BY da janela. Duas linhas nunca compartilham um número, mesmo quando seus valores de ordenação são idênticos.

Essa exclusividade é exatamente o motivo pelo qual os entrevistadores recorrem a ela para resolver problemas de «escolher uma linha por grupo» e de desduplicação. As outras funções de classificação (RANK, DENSE_RANK) não prometem exclusividade em caso de empate.

Consulta mínima com ROW_NUMBER

A forma mais simples numera todo um conjunto de resultados na ordem escolhida. ROW_NUMBER sempre precisa de um ORDER BY dentro de OVER — sem ele, a numeração seria arbitrária, e a maioria dos mecanismos de banco de dados rejeita a consulta ou emite um aviso.

Aqui, o funcionário contratado mais recentemente fica na linha 1 se você ordenar pela data de contratação em ordem decrescente.

SELECT
  name,
  hire_date,
  ROW_NUMBER() OVER (ORDER BY hire_date DESC) AS rn
FROM employees;

Numeração dentro de partições

Adicione PARTITION BY para numerar as linhas de forma independente dentro de cada grupo. O contador é reiniciado em 1 a cada novo valor de partição.

No exemplo, cada departamento recebe sua própria sequência 1, 2, 3, ordenada pelo salário. O funcionário com maior salário de cada departamento recebe o número 1 — a base do padrão dos N primeiros por grupo.

SELECT
  department,
  name,
  salary,
  ROW_NUMBER() OVER (
    PARTITION BY department
    ORDER BY salary DESC
  ) AS dept_rn
FROM employees;

ROW_NUMBER e empates: não há empates

Ponto fundamental em entrevistas técnicas: quando duas linhas têm valores de ordenação iguais, ROW_NUMBER ainda atribui a elas números diferentes. Qual delas recebe o número menor é não determinístico, a menos que você adicione uma coluna de desempate.

  • RANK atribuiria a mesma classificação às linhas empatadas.
  • ROW_NUMBER escolhe arbitrariamente uma ordem entre elas.

Para tornar os resultados reproduzíveis, sempre adicione um critério de desempate exclusivo ao ORDER BY.

SELECT
  name,
  salary,
  ROW_NUMBER() OVER (
    ORDER BY salary DESC, employee_id  -- employee_id breaks ties deterministically
  ) AS rn
FROM employees;

A regra do critério de desempate determinístico

Se o seu ORDER BY não estabelece uma ordem estrita (nenhuma combinação de colunas é exclusiva), a numeração das linhas pode mudar entre execuções, mesmo com os mesmos dados. Os entrevistadores inserem essa armadilha em perguntas sobre paginação e «registro mais recente».

Regra prática: adicione uma chave primária ou outra coluna exclusiva como último critério de ordenação sempre que o resultado precisar ser estável.

-- Unstable: many rows can share the same created_at
ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY created_at DESC)

-- Stable: id guarantees a single deterministic winner
ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY created_at DESC, id DESC)

Exemplo resolvido: pedido mais recente por cliente

Uma pergunta clássica: «Retorne o pedido mais recente de cada cliente». Numere os pedidos de cada cliente pela data em ordem decrescente e, em seguida, mantenha rn = 1 em uma consulta externa.

Como ROW_NUMBER garante exatamente uma linha com o número 1 por partição, você obtém precisamente uma linha por cliente — sem duplicatas, mesmo que dois pedidos compartilhem o mesmo registro de data e hora (o critério de desempate resolve a situação).

SELECT customer_id, order_id, order_date, amount
FROM (
  SELECT
    customer_id, order_id, order_date, amount,
    ROW_NUMBER() OVER (
      PARTITION BY customer_id
      ORDER BY order_date DESC, order_id DESC
    ) AS rn
  FROM orders
) t
WHERE rn = 1;

Exemplo resolvido: desduplicação de linhas

ROW_NUMBER é a ferramenta mais simples para desduplicação. Particione pelas colunas que definem uma duplicata, ordene segundo uma regra de preferência e, em seguida, mantenha rn = 1.

Aqui, tratamos as linhas com o mesmo e-mail como duplicatas e mantemos a criada primeiro. Tudo com rn > 1 é uma duplicata que você pode excluir ou ignorar.

SELECT id, email, created_at
FROM (
  SELECT
    id, email, created_at,
    ROW_NUMBER() OVER (
      PARTITION BY email
      ORDER BY created_at ASC, id ASC
    ) AS rn
  FROM users
) t
WHERE rn = 1;

ROW_NUMBER para paginação

Antes de OFFSET/FETCH se tornar universal, ROW_NUMBER conduzia a paginação, e ainda é usado no SQL Server e em muitos trabalhos de ETL. Numere as linhas em uma ordem estável e, em seguida, filtre um intervalo numerado em uma consulta externa.

Atenção em entrevistas técnicas: a paginação só é correta se a ordenação for determinística — caso contrário, a mesma linha pode aparecer em duas páginas ou ser totalmente ignorada.

SELECT *
FROM (
  SELECT *, ROW_NUMBER() OVER (ORDER BY created_at, id) AS rn
  FROM articles
) t
WHERE rn BETWEEN 21 AND 40;  -- page 2, 20 per page

Atribuindo uma sequência para reordenar dados

Às vezes, você só precisa de um índice sequencial, por exemplo, para renumerar linhas depois de uma ordenação, criar um rótulo de 1 a N ou parear linhas com uma série gerada. ROW_NUMBER aplicado à ordem desejada produz uma sequência densa e limpa, sem lacunas.

Essa também é a forma de atribuir uma posição estável a um conjunto arbitrário e não ordenado para fazer uma junção posteriormente.

SELECT
  ROW_NUMBER() OVER (ORDER BY score DESC, player_id) AS leaderboard_position,
  player_id,
  score
FROM scores;

ROW_NUMBER versus COUNT para a «enésima linha»

Quando pedirem «o terceiro pedido mais recente» ou «a segunda linha», use ROW_NUMBER e filtre pelo valor exato em uma consulta externa. Como a numeração é exclusiva, rn = 3 retorna exatamente uma linha.

Compare com RANK: se você quiser o segundo valor distinto (por exemplo, o segundo maior salário incluindo empates), ROW_NUMBER é a ferramenta errada — nesse caso, você precisa de DENSE_RANK, abordado na próxima lição.

SELECT order_id, order_date
FROM (
  SELECT order_id, order_date,
         ROW_NUMBER() OVER (ORDER BY order_date DESC, order_id DESC) AS rn
  FROM orders
) t
WHERE rn = 3;  -- exactly the 3rd most recent order

Recapitulação das armadilhas

Tenha estes pontos claros sob a pressão de uma entrevista técnica:

  • ROW_NUMBER é sempre exclusivo e sem lacunas dentro de uma partição.
  • Ele precisa de um ORDER BY em OVER; sem um critério de desempate exclusivo, os resultados não são determinísticos em caso de empate.
  • Não é possível filtrá-lo em WHERE — envolva-o em uma subconsulta/CTE.
  • Use-o para obter uma linha por grupo, fazer desduplicação e paginação; use DENSE_RANK quando os empates precisarem compartilhar um número.

Verificação rápida

Como ROW_NUMBER trata as linhas empatadas no valor de ORDER BY?

Recapitulação: sequenciamento determinístico

ROW_NUMBER é a sua ferramenta para obter uma numeração exclusiva e sem lacunas dentro das partições. Você aprendeu a:

  • Numerar conjuntos inteiros e grupos por partição.
  • Adicionar um critério de desempate exclusivo para obter resultados determinísticos e reproduzíveis.
  • Resolver problemas de última linha por chave, desduplicação, paginação e enésima linha filtrando rn em uma consulta externa.

Em seguida, você verá como RANK e DENSE_RANK dão deliberadamente o mesmo número aos empates — e como o comportamento das lacunas é diferente entre elas.

Perguntas Frequentes

A aula “ROW_NUMBER para sequenciamento exclusivo” é grátis?

Sim — o texto completo de “ROW_NUMBER para sequenciamento exclusivo” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de SQL Interview Prep, atualize para CoddyKit PRO. O curso de SQL Interview Prep inclui 4 aulas no total.

O que vou aprender em “ROW_NUMBER para sequenciamento exclusivo”?

Atribua um número de linha determinístico dentro de cada partição. Você pratica SQL Interview Prep com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar SQL Interview Prep?

Nenhuma experiência prévia é necessária. SQL Interview Prep no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 2 de 4.

Quanto tempo leva a aula “ROW_NUMBER para sequenciamento exclusivo”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de SQL Interview Prep?

Sim. Cada aula de SQL Interview Prep inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. OVER, PARTITION BY e ORDER BY
  2. ROW_NUMBER para sequenciamento exclusivo
  3. RANK versus DENSE_RANK em empates
  4. Filtrando um resultado de janela
← Voltar para SQL Interview Prep