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 90Observaçõ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_NUMBERpara "N-ésimo maior" e deixar de incluir linhas empatadas. - Usar
RANKquando a pergunta se refere a valores distintos e depois obter resultados vazios por causa das lacunas. - Esquecer
ORDER BYdentro deOVER— 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
- OVER, PARTITION BY e ORDER BY
- ROW_NUMBER para sequenciamento exclusivo
- RANK versus DENSE_RANK em empates
- Filtrando um resultado de janela