0Pricing
SQL Interview Prep · Aula

RANK versus DENSE_RANK em empates

A pergunta clássica sobre classificações com lacunas ou sem lacunas quando há empate nos valores.

RANK versus DENSE_RANK em empates é uma aula grátis de SQL Interview Prep no CoddyKit. Esta é a aula 3 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.

As três funções de classificação lado a lado

O SQL oferece três funções de janela para classificação, e a pergunta mais frequente sobre janelas é como elas diferem em caso de empate:

  • ROW_NUMBER — sempre exclusivo; os empates recebem números distintos arbitrários.
  • RANK — os empates compartilham uma classificação e, em seguida, a próxima classificação pula (deixa uma lacuna).
  • DENSE_RANK — os empates compartilham uma classificação e, em seguida, a próxima classificação não pula (não há lacuna).

Conseguir recitar essa diferença imediatamente é um indicador confiável em entrevistas técnicas.

Uma tabela de exemplo concreta

Imagine cinco pontuações ordenadas de forma decrescente: 100, 90, 90, 80, 70. Observe como cada função as numera.

  • ROW_NUMBER: 1, 2, 3, 4, 5
  • RANK: 1, 2, 2, 4, 5 (pula o 3 depois do empate)
  • DENSE_RANK: 1, 2, 2, 3, 4 (não pula)

Memorize este exemplo com 100/90/90/80/70 — ele responde à pergunta imediatamente.

SELECT
  score,
  ROW_NUMBER()  OVER (ORDER BY score DESC) AS rownum,
  RANK()        OVER (ORDER BY score DESC) AS rnk,
  DENSE_RANK()  OVER (ORDER BY score DESC) AS dense
FROM scores;

Como RANK calcula a lacuna

RANK atribui a cada linha uma classificação igual a um mais o número de linhas que a precedem estritamente na ordem. Duas linhas empatadas no valor 90 são precedidas por uma linha cada (a de valor 100), portanto ambas recebem a classificação 2. O próximo valor menor é precedido por três linhas, então salta para a classificação 4.

É por isso que RANK reproduz a pontuação de competições: medalhistas de prata empatados, sem medalha de bronze.

-- scores 100,90,90,80 -> RANK = 1,2,2,4
SELECT score, RANK() OVER (ORDER BY score DESC) AS rnk
FROM scores;

Como DENSE_RANK evita a lacuna

DENSE_RANK atribui uma classificação igual a um mais o número de valores distintos que precedem o valor atual. Depois do empate em 90, apenas dois valores distintos vieram antes de 80 (100 e 90), então ele recebe a classificação 3 — sem lacuna.

Use DENSE_RANK quando você se importar com posições de valores distintos, como em «o segundo maior salário», em que os empates devem contar uma única vez.

-- scores 100,90,90,80 -> DENSE_RANK = 1,2,2,3
SELECT score, DENSE_RANK() OVER (ORDER BY score DESC) AS dense
FROM scores;

Quando escolher cada função

Um guia rápido de decisão que os entrevistadores gostam de ouvir:

  • Precisa de exatamente uma linha por posição (registro mais recente, paginação)? → ROW_NUMBER.
  • Precisa de uma classificação em que os empates compartilhem a posição e as lacunas estejam corretas (classificação esportiva, 3 primeiros incluindo empates)? → RANK.
  • Precisa do N-ésimo valor distinto (N-ésimo maior salário)? → DENSE_RANK.

A escolha errada altera as linhas retornadas, portanto justifique sua escolha em voz alta.

Classificação dentro de partições

As três funções aceitam PARTITION BY para fazer a classificação de forma independente dentro de cada grupo. Cada partição começa novamente na classificação 1.

Aqui, cada departamento classifica seus próprios funcionários por salário, tratando os empates com DENSE_RANK. O funcionário com maior salário de cada departamento fica na classificação 1, e os funcionários com o mesmo salário compartilham a classificação.

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

Exemplo resolvido: 3 primeiros, incluindo empates

"Retorne os 3 maiores salários por departamento e, se várias pessoas empatarem em terceiro lugar, inclua todas." Isso exige RANK ou DENSE_RANK, não ROW_NUMBER.

Usar DENSE_RANK <= 3 mantém os três níveis de salário distintos mais altos e todos os funcionários nesses níveis — exatamente o que significa "incluindo empates".

SELECT department, name, salary, salary_rank
FROM (
  SELECT department, name, salary,
         DENSE_RANK() OVER (
           PARTITION BY department ORDER BY salary DESC
         ) AS salary_rank
  FROM employees
) t
WHERE salary_rank <= 3;

Exemplo resolvido: segundo maior salário

A pergunta mais famosa de entrevistas sobre SQL. A resposta robusta usa DENSE_RANK para que salários máximos duplicados não impeçam o acesso ao segundo valor real.

Se três pessoas recebem o salário máximo, DENSE_RANK = 2 ainda identifica corretamente o próximo salário distinto, enquanto ROW_NUMBER = 2 simplesmente retornaria outra pessoa com o salário máximo.

SELECT DISTINCT salary AS second_highest
FROM (
  SELECT salary, DENSE_RANK() OVER (ORDER BY salary DESC) AS dr
  FROM employees
) t
WHERE dr = 2;

RANK ou DENSE_RANK para o “N-ésimo maior”

Por que usar DENSE_RANK em vez de RANK em desafios sobre o N-ésimo maior valor? Porque RANK deixa lacunas. Com os salários 100, 100, 90, o valor 90 tem RANK = 3, mas DENSE_RANK = 2.

Se a pergunta solicitar o "2º maior salário distinto", filtrar por RANK = 2 não retornará nada, enquanto DENSE_RANK = 2 retornará corretamente 90. Sempre associe "N-ésimo distinto" a DENSE_RANK.

-- salaries 100,100,90
-- RANK:       1,1,3   -> WHERE rank = 2 returns NOTHING
-- DENSE_RANK: 1,1,2   -> WHERE dense_rank = 2 returns 90

Observações entre dialetos

Uma boa notícia: ROW_NUMBER, RANK e DENSE_RANK fazem parte do padrão SQL e se comportam de forma idêntica em PostgreSQL, SQL Server, Oracle, MySQL 8+, BigQuery e Snowflake. A semântica de empates acima é universal.

Uma função relacionada, PERCENT_RANK, baseia-se em RANK para fornecer uma posição relativa de 0 a 1 — vale a pena mencioná-la se um entrevistador perguntar sobre classificação por percentil.

Erros comuns

Atenção a estes pontos:

  • Usar ROW_NUMBER para "N-ésimo maior" e deixar de incluir linhas empatadas.
  • Usar RANK quando a pergunta se refere a valores distintos e depois obter resultados vazios por causa das lacunas.
  • Esquecer ORDER BY dentro de OVER — a classificação não tem sentido sem isso.
  • Filtrar a classificação diretamente em WHERE, em vez de fazer isso em uma consulta externa.

Verificação rápida

Aplique as regras de empate.

Recapitulação: com lacunas vs. sem lacunas

Agora você pode escolher instantaneamente a função de classificação correta:

  • ROW_NUMBER: números exclusivos, sem classificações compartilhadas.
  • RANK: os empates compartilham uma classificação, seguida de uma lacuna (1,2,2,4).
  • DENSE_RANK: os empates compartilham uma classificação, sem lacuna (1,2,2,3).
  • "N-ésimo maior distinto" → DENSE_RANK; "N primeiros, incluindo empates" → RANK/DENSE_RANK; "uma linha por posição" → ROW_NUMBER.

A seguir: como filtrar de fato um resultado de janela, pois isso não pode ser feito em WHERE.

Perguntas Frequentes

A aula “RANK versus DENSE_RANK em empates” é grátis?

Sim — o texto completo de “RANK versus DENSE_RANK em empates” é 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 “RANK versus DENSE_RANK em empates”?

A pergunta clássica sobre classificações com lacunas ou sem lacunas quando há empate nos valores. 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 3 de 4.

Quanto tempo leva a aula “RANK versus DENSE_RANK em empates”?

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