Retornando as linhas Top-N de forma confiável
Entenda por que ORDER BY com LIMIT pode ser não determinístico sem um critério de desempate.
Retornando as linhas Top-N de forma confiável é 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.
O erro oculto nas consultas dos N primeiros resultados
"Mostre os 5 funcionários com os maiores salários" parece fácil: ORDER BY salary DESC LIMIT 5. Mas os entrevistadores preparam uma armadilha. E se seis pessoas tiverem o mesmo salário no limite? E se muitas linhas empatarem?
O problema central é o determinismo: quando a chave de ordenação tem empates, LIMIT faz o corte arbitrariamente, e as linhas exatas retornadas podem mudar entre as execuções. Esta lição torna confiáveis as consultas dos N primeiros resultados.
Por que ORDER BY + LIMIT pode ser não determinístico
Considere salários em que as posições 4, 5 e 6 sejam todas 50000. ORDER BY salary DESC LIMIT 5 precisa retornar exatamente 5 linhas, então mantém duas das três linhas empatadas e descarta uma, mas não se sabe quais duas.
Execute a consulta duas vezes, ou depois que o otimizador mudar os planos, e talvez você obtenha pessoas diferentes. Esse não determinismo é o erro que os entrevistadores querem que você identifique.
SELECT name, salary
FROM employees
ORDER BY salary DESC
LIMIT 5;Correção 1: adicione um critério de desempate único
A correção mais simples é tornar a ordem de ordenação total, acrescentando uma coluna que seja única, geralmente a chave primária. Agora não há duas linhas iguais em relação à chave completa, portanto o corte é determinístico e reproduzível.
Isso não muda quais salários aparecem, mas torna estável, entre as execuções, a escolha entre as linhas empatadas.
SELECT id, name, salary
FROM employees
ORDER BY salary DESC, id ASC
LIMIT 5;Correção 2: inclua todos os empates com WITH TIES
Às vezes, o requisito é "incluir todas as pessoas empatadas com o limite", e não retornar exatamente N linhas. O SQL padrão e o SQL Server oferecem WITH TIES, que retorna linhas adicionais com o mesmo valor de ORDER BY da última linha.
Se o quinto salário for compartilhado por três pessoas, serão retornadas 7 linhas. Observe que WITH TIES exige um ORDER BY.
SELECT name, salary
FROM employees
ORDER BY salary DESC
FETCH FIRST 5 ROWS WITH TIES;Esclareça o requisito primeiro
Antes de programar, pergunte ao entrevistador: "Se houver empates no limite, você deseja exatamente N linhas ou todas as linhas empatadas?" Essa única pergunta de esclarecimento demonstra experiência.
- Exatamente N, de forma estável: adicione um critério de desempate único.
- Incluir todos os empates: use
WITH TIESouRANK. - Valores distintos: use
DENSE_RANK.
A abordagem portável com função de janela
Muitos mecanismos não têm WITH TIES. O padrão portável e poderoso usa uma função de janela de classificação em uma subconsulta ou CTE e, em seguida, filtra pela classificação. ROW_NUMBER fornece exatamente N linhas com uma chave de ordenação determinística.
Você precisa envolver a função de janela porque não pode referenciá-la diretamente em WHERE.
SELECT name, salary
FROM (
SELECT name, salary,
ROW_NUMBER() OVER (ORDER BY salary DESC, id ASC) AS rn
FROM employees
) ranked
WHERE rn <= 5;RANK para manter empates
Troque ROW_NUMBER por RANK quando quiser manter todas as linhas empatadas e deixar lacunas na numeração. Se três linhas empatarem na posição 4, todas receberão a posição 4 e a próxima posição será 7.
Filtrar por rank <= 5 retorna todas as linhas nas cinco primeiras posições salariais, incluindo os empates.
SELECT name, salary
FROM (
SELECT name, salary,
RANK() OVER (ORDER BY salary DESC) AS rnk
FROM employees
) ranked
WHERE rnk <= 5;DENSE_RANK para os N primeiros valores distintos
"Níveis salariais dos 3 primeiros" (não as 3 primeiras pessoas) significa valores distintos. DENSE_RANK atribui a mesma posição aos empates e não pula números, portanto dense_rnk <= 3 retorna todas as pessoas que ganham um dos três maiores salários distintos.
Saber qual função de classificação corresponde a cada formulação é um diferencial clássico.
SELECT name, salary
FROM (
SELECT name, salary,
DENSE_RANK() OVER (ORDER BY salary DESC) AS drnk
FROM employees
) ranked
WHERE drnk <= 3;Caso especial do primeiro colocado
Para uma única linha no topo, ORDER BY ... LIMIT 1 funciona, mas ainda corre o risco de ignorar empates. Se quiser todas as linhas que tenham o valor máximo, compare com o máximo de uma subconsulta ou use RANK() = 1.
A forma com subconsulta do valor máximo é simples e funciona em qualquer dialeto.
SELECT name, salary
FROM employees
WHERE salary = (SELECT MAX(salary) FROM employees);Comparando as abordagens
Resumo de quando usar cada ferramenta para obter os N primeiros resultados de forma confiável:
LIMIT+ critério de desempate único: exatamente N linhas, estáveis e de forma simples.FETCH ... WITH TIES: exatamente N linhas mais os empates no limite, no SQL padrão.ROW_NUMBER: exatamente N linhas, determinísticas e totalmente portáveis.RANK: as N primeiras posições, incluindo todos os empates.DENSE_RANK: os N primeiros valores distintos.
Prévia dos N primeiros por grupo
A abordagem com funções de janela é muito generalizável. Adicione PARTITION BY para obter os N primeiros dentro de cada grupo, por exemplo, as duas pessoas com maiores salários de cada departamento. O mesmo filtro rn <= n se aplica depois do particionamento.
Obter os N primeiros por grupo é um dos problemas reais mais frequentes em entrevistas, baseado exatamente no padrão que você acabou de aprender.
SELECT department, name, salary
FROM (
SELECT department, name, salary,
ROW_NUMBER() OVER (PARTITION BY department
ORDER BY salary DESC, id ASC) AS rn
FROM employees
) ranked
WHERE rn <= 2;Verificação rápida
Associe o requisito à função correta.
Recapitulação
Para retornar os N primeiros resultados de forma confiável:
ORDER BY ... LIMITsozinho é não determinístico quando a chave de ordenação tem empates.- Adicione um critério de desempate único para obter resultados estáveis com exatamente N linhas.
- Use
WITH TIESouRANKpara manter os empates no limite. - Use
DENSE_RANKpara obter os N primeiros valores distintos. - Sempre esclareça se o entrevistador deseja exatamente N linhas ou todos os empates.
Aprenda SQL 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
- 30
- Aulas
- 120
Perguntas Frequentes
A aula “Retornando as linhas Top-N de forma confiável” é grátis?
Sim — o texto completo de “Retornando as linhas Top-N de forma confiável” é 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 “Retornando as linhas Top-N de forma confiável”?
Entenda por que ORDER BY com LIMIT pode ser não determinístico sem um critério de desempate. 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 “Retornando as linhas Top-N de forma confiável”?
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
- Ordenação por várias colunas e posicionamento de NULL
- LIMIT, OFFSET e FETCH FIRST
- Retornando as linhas Top-N de forma confiável
- Ordenando por expressões e aliases