Lidando com empates em Top-N
Saiba quando usar RANK ou DENSE_RANK para incluir todas as linhas empatadas.
Lidando com empates em Top-N é uma aula grátis de Coding 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 Coding Interview Prep, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Coding Interview Prep inclui 4 aulas no total.
A pergunta de acompanhamento sobre empates
Depois que você domina os N maiores com ROW_NUMBER, o entrevistador aprofunda a questão: “E se dois funcionários tiverem exatamente o mesmo salário no limite? Os dois devem ser incluídos?”
Isso diferencia os candidatos que memorizaram uma consulta daqueles que entendem a semântica da classificação. A resposta depende da escolha entre ROW_NUMBER, RANK e DENSE_RANK. Esta lição relaciona cada função à intenção do negócio.
ROW_NUMBER oculta os empates
ROW_NUMBER atribui um inteiro estritamente único a cada linha. Mesmo quando duas linhas empatam na coluna de ordenação, uma recebe 2 e a outra recebe 3 em alguma ordem arbitrária.
Consequência: um filtro WHERE rn <= 3 retorna exatamente 3 linhas e pode eliminar silenciosamente uma linha empatada que, razoavelmente, deveria ser incluída. Isso é adequado quando você realmente quer uma quantidade fixa, mas está errado quando todas as linhas empatadas devem se qualificar.
-- Salaries: 100, 90, 90, 80
-- ROW_NUMBER -> 1, 2, 3, 4 (the two 90s get 2 and 3 arbitrarily)
ROW_NUMBER() OVER (ORDER BY salary DESC)RANK deixa lacunas
RANK atribui a mesma classificação às linhas empatadas e depois pula os valores seguintes para levar os empates em conta. Duas linhas empatadas na posição 2 recebem 2, e a linha seguinte passa para a posição 4, não 3.
Use RANK quando quiser as “3 primeiras posições” e uma posição puder ser ocupada por várias pessoas, imitando classificações reais de competições, nas quais dois medalhistas de prata significam que não há medalhista de bronze.
-- Salaries: 100, 90, 90, 80
-- RANK -> 1, 2, 2, 4 (rank 3 is skipped)
RANK() OVER (ORDER BY salary DESC)DENSE_RANK não tem lacunas
DENSE_RANK também atribui a mesma classificação às linhas empatadas, mas não pula posições depois do empate. Duas linhas empatadas na posição 2 recebem 2, e o próximo valor distinto recebe 3.
Use DENSE_RANK quando a pergunta for sobre valores distintos: “os 3 níveis salariais distintos mais altos” ou “as 3 principais faixas de preço”. Essa função conta valores únicos, não linhas.
-- Salaries: 100, 90, 90, 80
-- DENSE_RANK -> 1, 2, 2, 3 (no gap)
DENSE_RANK() OVER (ORDER BY salary DESC)Comparação lado a lado
Para a lista de salários 100, 90, 90, 80, as três funções produzem:
- ROW_NUMBER: 1, 2, 3, 4
- RANK: 1, 2, 2, 4
- DENSE_RANK: 1, 2, 2, 3
Vale a pena memorizar bem esta tabela. O entrevistador pode simplesmente pedir que você a preencha para uma determinada lista, e acertar o comportamento das lacunas é o objetivo principal.
SELECT salary,
ROW_NUMBER() OVER (ORDER BY salary DESC) AS rn,
RANK() OVER (ORDER BY salary DESC) AS rnk,
DENSE_RANK() OVER (ORDER BY salary DESC) AS drnk
FROM employees;Inclua todas as linhas empatadas com RANK
Para responder a “3 maiores, mas incluindo todos os empatados no limite”, filtre por RANK() <= 3. Se duas pessoas compartilharem a posição 3, ambas aparecerão; portanto, o resultado poderá conter mais de 3 linhas.
Essa é a intenção por trás de perguntas formuladas como “as 3 primeiras posições”, e não “quaisquer 3 linhas”. Informe explicitamente que a quantidade de linhas pode exceder N quando houver empates.
WITH ranked AS (
SELECT name, department, salary,
RANK() OVER (
PARTITION BY department ORDER BY salary DESC
) AS rnk
FROM employees
)
SELECT name, department, salary, rnk
FROM ranked
WHERE rnk <= 3
ORDER BY department, rnk;Os 3 níveis distintos mais altos com DENSE_RANK
Quando o requisito for “os 3 níveis salariais distintos mais altos” e você quiser todos os funcionários nesses três níveis, use DENSE_RANK() <= 3.
Isso pode retornar muitas linhas: todos os funcionários nas três faixas salariais mais altas, independentemente de quantos funcionários estejam em cada faixa. A ideia principal é que DENSE_RANK conta valores distintos; portanto, o filtro seleciona faixas de valores, e não uma quantidade fixa de linhas.
WITH ranked AS (
SELECT name, salary,
DENSE_RANK() OVER (ORDER BY salary DESC) AS drnk
FROM employees
)
SELECT name, salary, drnk
FROM ranked
WHERE drnk <= 3
ORDER BY drnk;Guia de decisão
Associe a formulação à função:
- “Exatamente N linhas” ou paginação →
ROW_NUMBER(adicione um critério de desempate). - “As N primeiras posições, com os empates compartilhando uma posição” →
RANK. - “Os N valores, níveis ou faixas distintos mais altos” →
DENSE_RANK.
Quando a especificação for ambígua, pergunte: “Se houver empate no limite, devo incluir todas as linhas empatadas ou limitar o resultado a N?” Essa pergunta de esclarecimento, por si só, rende pontos.
Os critérios de desempate continuam importantes
Mesmo com RANK ou DENSE_RANK, adicionar uma chave secundária de ORDER BY controla a ordem de exibição das linhas empatadas e mantém a saída estável. Isso não altera quais linhas se qualificam, mas torna os resultados reproduzíveis.
Com ROW_NUMBER, o critério de desempate é essencial, pois determina qual linha empatada permanecerá após o limite de rn.
RANK() OVER (
PARTITION BY department
ORDER BY salary DESC, name ASC
) AS rnkExemplo prático: os maiores pontuadores
Uma tabela game_scores tem player e score. O entrevistador quer “todos os jogadores nas 2 primeiras posições de pontuação”. Um empate no primeiro lugar significa dois jogadores na posição 1; depois, a próxima pontuação distinta ocupa a posição 2.
“Posições” sem pular posições depois de um empate indica DENSE_RANK. Se, em vez disso, a pergunta fosse “as 2 primeiras posições da classificação com lacunas”, você usaria RANK. Preste atenção à formulação exata.
WITH r AS (
SELECT player, score,
DENSE_RANK() OVER (ORDER BY score DESC) AS pos
FROM game_scores
)
SELECT player, score, pos
FROM r
WHERE pos <= 2
ORDER BY pos, player;Erros comuns a evitar
Armadilhas que os entrevistadores observam:
- Usar
ROW_NUMBERquando a pergunta exige incluir empates, eliminando silenciosamente uma linha que deveria ser qualificada. - Confundir o comportamento das lacunas de
RANKeDENSE_RANK. - Esquecer que os filtros de
RANK/DENSE_RANKpodem retornar mais de N linhas e depois afirmar que o resultado está errado. - Omitir
PARTITION BYquando os N maiores devem ser obtidos por grupo, classificando a tabela inteira em vez disso.
Verificação rápida
Escolha a função de classificação correta para o comportamento de empates descrito.
Resumo: tratamento de empates
Três funções, três comportamentos em caso de empate:
- ROW_NUMBER: sempre exclusivo, exatamente N linhas, empates desfeitos arbitrariamente.
- RANK: os empates compartilham uma posição, depois surgem lacunas.
- DENSE_RANK: os empates compartilham uma posição, sem lacunas, contando valores distintos.
Escolha com base na formulação da pergunta, faça uma pergunta de esclarecimento quando houver ambiguidade e lembre-se de que os filtros RANK/DENSE_RANK podem retornar mais de N linhas por definição.
Aprenda Coding Interview Prep com um tutor de IA — grátis
Escreva e execute código real no seu navegador, obtenha ajuda instantânea de um tutor de IA 24/7 e continue de onde parou na web ou no app.
- Cursos
- 90
- Aulas
- 360
Perguntas Frequentes
A aula “Lidando com empates em Top-N” é grátis?
Sim — o texto completo de “Lidando com empates em Top-N” é 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 Coding Interview Prep, atualize para CoddyKit PRO. O curso de Coding Interview Prep inclui 4 aulas no total.
O que vou aprender em “Lidando com empates em Top-N”?
Saiba quando usar RANK ou DENSE_RANK para incluir todas as linhas empatadas. Você pratica Coding 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 Coding Interview Prep?
Nenhuma experiência prévia é necessária. Coding 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 “Lidando com empates em Top-N”?
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 Coding Interview Prep?
Sim. Cada aula de Coding 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
- Linhas Top-N por grupo com ROW_NUMBER
- Lidando com empates em Top-N
- Eliminando duplicatas de linhas com segurança
- Mantendo a linha mais recente por chave