Retornando NULL quando não existe o enésimo valor
Conheça o caso extremo que os entrevistadores adoram: lidar adequadamente com poucas linhas.
Retornando NULL quando não existe o enésimo valor é uma aula grátis de Coding Interview Prep no CoddyKit. Esta é a aula 4 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.
O caso extremo que os entrevistadores adoram
Depois que você acertar a consulta do N-ésimo maior valor, o entrevistador acrescenta: “E se a tabela tiver menos de N salários distintos? Quero um único NULL, não um resultado vazio.”
Esta é a pergunta que diferencia candidatos que decoraram uma consulta daqueles que entendem o comportamento do conjunto de resultados. Muitas soluções retornam silenciosamente zero linhas, em vez de uma linha contendo NULL.
Esta lição trata de forçar exatamente uma linha de saída, cujo valor seja NULL quando não existir o valor na posição N.
Por que DENSE_RANK sozinho não retorna linhas
Recorde a consulta padrão do N-ésimo maior valor. Se houver apenas dois salários distintos e você pedir o 3º, WHERE rnk = 3 não encontrará correspondências, portanto a consulta retornará um conjunto vazio: zero linhas.
Um conjunto vazio não é igual a uma linha contendo NULL. Se a especificação disser “retorne NULL”, a consulta falhará no teste, mesmo que a lógica subjacente esteja correta.
SELECT salary
FROM (
SELECT salary,
DENSE_RANK() OVER (ORDER BY salary DESC) AS rnk
FROM employee
) t
WHERE rnk = 3; -- returns NO rows if fewer than 3 distinct salariesCorreção 1: envolva em um SELECT externo
A correção confiável mais simples: transforme toda a consulta do N-ésimo maior valor em uma subconsulta escalar dentro de um único SELECT. Uma subconsulta escalar sem correspondências é avaliada como NULL, e o SELECT externo sempre produz exatamente uma linha.
Esta é a resposta padrão para a variante no estilo LeetCode de “retornar NULL” e funciona em todos os dialetos.
SELECT (
SELECT DISTINCT salary
FROM employee
ORDER BY salary DESC
LIMIT 1 OFFSET 2 -- N = 3
) AS third_highest;Por que o truque da subconsulta escalar funciona
Dois princípios se combinam para produzir o comportamento desejado:
- Uma subconsulta escalar deve retornar no máximo um valor. Se não retornar linhas, o SQL substitui o resultado por
NULL. - O SELECT externo sem
FROM(ou com uma fonte de uma única linha) sempre emite exatamente uma linha.
Assim, quando a consulta interna encontra o valor na posição N, você o obtém; quando não encontra nada, recebe uma linha contendo NULL. Exatamente o contrato declarado pelo entrevistador.
Correção 1 com a versão DENSE_RANK
O mesmo invólucro funciona com a solução que usa funções de janela. Coloque a consulta classificada dentro da subconsulta escalar; se nenhuma linha tiver a classificação N, a subconsulta produzirá NULL e o SELECT externo ainda retornará uma linha.
SELECT (
SELECT salary
FROM (
SELECT salary,
DENSE_RANK() OVER (ORDER BY salary DESC) AS rnk
FROM employee
) t
WHERE rnk = 3
) AS third_highest;Correção 2: MAX retorna NULL automaticamente
Relembre a ideia de MAX abaixo de MAX da lição 1. Uma agregação sobre zero linhas retorna NULL e ainda produz uma linha. Para o segundo maior valor, esta é uma solução concisa que já atende ao requisito de NULL.
A desvantagem: estender o aninhamento puro de MAX para um N arbitrário fica complicado, portanto isso é melhor especificamente para o caso do 2º maior valor.
SELECT MAX(salary) AS second_highest
FROM employee
WHERE salary < (SELECT MAX(salary) FROM employee);Correção 3: COALESCE com um valor alternativo
Se o seu ambiente garantir uma linha, mas o valor puder estar ausente por algum outro motivo, você poderá envolver o resultado em COALESCE para fornecer um valor padrão explícito.
Observe: COALESCE só ajuda depois que uma linha existe. Não transforma um conjunto de resultados vazio em uma linha. Portanto, combine-o com o invólucro da subconsulta escalar (que garante uma linha) e, em seguida, aplique COALESCE ao valor se quiser algo diferente de NULL, como 0.
SELECT COALESCE((
SELECT DISTINCT salary
FROM employee
ORDER BY salary DESC
LIMIT 1 OFFSET 2
), 0) AS third_highest_or_zero;O que não corrige isso
Cuidado com correções que parecem certas, mas falham:
- Adicionar
COALESCEdiretamente em torno de uma consulta que retorna zero linhas não faz nada; não há uma linha paraCOALESCEprocessar. IFNULL/ISNULLtêm a mesma limitação queCOALESCE.- Adicionar
LIMIT 1não cria uma linha quando nenhuma linha atende aos critérios.
O problema da quantidade de linhas deve ser resolvido com o invólucro da subconsulta escalar ou com uma agregação, não apenas com funções de substituição de NULL.
Exemplo resolvido: pedindo o 3º entre dois
Salários: 500, 500, 300. Os salários distintos são apenas 500 e 300, portanto não existe um 3º maior.
- DENSE_RANK simples com WHERE rnk = 3: retorna zero linhas. Não atende à especificação.
- Invólucro de subconsulta escalar: a consulta interna não encontra nada, então o SELECT externo retorna uma linha:
NULL. Atende à especificação. - COALESCE(..., 0): retorna uma linha:
0, se um valor padrão numérico tiver sido solicitado.
Explicando isso na entrevista
Ganhe pontos narrando:
- “A consulta ingênua retorna um conjunto vazio, não NULL, então vou envolvê-la em uma subconsulta escalar para garantir uma linha.”
- “Uma subconsulta escalar sem linhas correspondentes é avaliada como NULL, que é exatamente o contrato.”
- “Se preferir um valor padrão como 0 em vez de NULL, adicionarei COALESCE em torno da subconsulta.”
Demonstrar que você entende a diferença entre a semântica da quantidade de linhas e a do valor é o objetivo desta pergunta.
Juntando tudo
Uma solução robusta e parametrizável para o N-ésimo maior valor ou NULL: classifique os salários distintos, filtre pela posição N dentro de uma subconsulta escalar e deixe o SELECT externo garantir uma única linha.
Esta consulta trata de duplicatas (por meio de DENSE_RANK), generaliza para qualquer N e retorna NULL de forma adequada quando N excede a quantidade de salários distintos.
SELECT (
SELECT salary
FROM (
SELECT salary,
DENSE_RANK() OVER (ORDER BY salary DESC) AS rnk
FROM employee
) t
WHERE rnk = :n
LIMIT 1
) AS nth_highest;Verificação rápida
Raciocine sobre a quantidade de linhas em comparação com os valores NULL.
Recapitulação
Quando N excede os salários distintos disponíveis, uma consulta simples de classificação retorna um conjunto vazio, não NULL.
- Envolva a consulta do N-ésimo maior valor em uma subconsulta escalar dentro de um SELECT externo para que ela sempre produza uma linha, resultando em
NULLquando nenhum valor corresponder. - A forma MAX abaixo de MAX retorna
NULLautomaticamente no caso do segundo maior valor. - COALESCE só substitui um valor depois que uma linha existe; não transforma zero linhas em uma.
Sempre diferencie a quantidade de linhas do valor quando o entrevistador pedir um tratamento adequado de NULL.
Perguntas Frequentes
A aula “Retornando NULL quando não existe o enésimo valor” é grátis?
Sim — o texto completo de “Retornando NULL quando não existe o enésimo valor” é 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 “Retornando NULL quando não existe o enésimo valor”?
Conheça o caso extremo que os entrevistadores adoram: lidar adequadamente com poucas linhas. 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 4 de 4.
Quanto tempo leva a aula “Retornando NULL quando não existe o enésimo valor”?
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
- Segundo maior salário: cinco maneiras
- Enésimo maior valor com DENSE_RANK
- Maior salário por departamento
- Retornando NULL quando não existe o enésimo valor