Maior salário por departamento
Combine particionamento e classificação para resolver problemas de maiores salários por grupo.
Maior salário por departamento é 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.
Da classificação global à classificação por grupo
O próximo nível é: "Encontre o funcionário mais bem pago de cada departamento." Isso combina classificação com agrupamento e é uma pergunta garantida para candidatos de nível intermediário.
Considere uma tabela employee com id, name, department_id e salary. Queremos um ou mais funcionários com o maior salário por departamento, em caso de empate, e não apenas o máximo global.
A nova ferramenta principal é PARTITION BY, que reinicia a classificação dentro de cada departamento.
CREATE TABLE employee (
id INT PRIMARY KEY,
name VARCHAR(100),
department_id INT,
salary INT
);PARTITION BY reinicia a classificação
Adicionar PARTITION BY department_id à janela informa ao banco de dados que a classificação deve ser calculada de forma independente dentro de cada departamento.
Cada departamento começa com sua própria classificação 1. Assim, o funcionário com o maior salário no departamento 1 e o funcionário com o maior salário no departamento 5 recebem a classificação 1. Sem particionamento, apenas o único máximo global receberia a classificação 1.
SELECT name, department_id, salary,
DENSE_RANK() OVER (
PARTITION BY department_id
ORDER BY salary DESC
) AS rnk
FROM employee;Filtrando pela classificação 1
Para manter apenas os funcionários com os maiores salários, encapsule a consulta classificada e filtre pela classificação 1. Como sempre, a função de janela precisa ser calculada em uma subconsulta ou CTE antes que seja possível filtrá-la.
Usar DENSE_RANK (ou RANK) aqui significa que, se dois funcionários empatarem com o maior salário de um departamento, ambos serão retornados. Essa geralmente é a interpretação correta de "o funcionário com o maior salário".
SELECT name, department_id, salary
FROM (
SELECT name, department_id, salary,
DENSE_RANK() OVER (
PARTITION BY department_id
ORDER BY salary DESC
) AS rnk
FROM employee
) t
WHERE rnk = 1;ROW_NUMBER quando quiser exatamente uma
Às vezes, o entrevistador quer exatamente uma linha por departamento, mesmo que haja um empate. Nesse caso, use ROW_NUMBER e adicione um critério de desempate determinístico, como o menor identificador.
Sem o critério de desempate, os empates são resolvidos arbitrariamente e o seu resultado não é determinístico. Adicionar , id ASC torna a escolha repetível.
SELECT name, department_id, salary
FROM (
SELECT name, department_id, salary,
ROW_NUMBER() OVER (
PARTITION BY department_id
ORDER BY salary DESC, id ASC
) AS rn
FROM employee
) t
WHERE rn = 1;DENSE_RANK vs ROW_NUMBER vs RANK aqui
Escolha com base na formulação exata:
- DENSE_RANK = 1: todos os funcionários empatados com o maior salário por departamento.
- RANK = 1: idêntico a DENSE_RANK para a primeira posição (as lacunas só importam abaixo da posição 1).
- ROW_NUMBER = 1: exatamente um funcionário por departamento, com os empates desfeitos pelo seu ORDER BY.
Dizer qual você escolheu e por quê é o que os entrevistadores avaliam.
A abordagem correlacionada anterior às funções de janela
Antes das funções de janela, a solução padrão era uma subconsulta correlacionada: mantenha uma linha apenas se ninguém no mesmo departamento receber um salário maior.
Isso retorna naturalmente todos os maiores salários empatados. A solução é portável, mas pode ser lenta porque o MAX interno é avaliado para cada linha externa, a menos que o otimizador o reescreva.
SELECT e.name, e.department_id, e.salary
FROM employee e
WHERE e.salary = (
SELECT MAX(e2.salary)
FROM employee e2
WHERE e2.department_id = e.department_id
);A abordagem de junção com GROUP BY
Outro padrão portável: calcule o salário máximo por departamento com GROUP BY e depois faça uma junção de volta para obter os funcionários correspondentes.
Essa abordagem é eficiente e clara. A junção traz de volta todos os funcionários cujo salário é igual ao máximo do departamento, portanto os empates são preservados.
SELECT e.name, e.department_id, e.salary
FROM employee e
JOIN (
SELECT department_id, MAX(salary) AS max_sal
FROM employee
GROUP BY department_id
) m
ON e.department_id = m.department_id
AND e.salary = m.max_sal;Os N maiores por departamento
O padrão se estende para "os 3 maiores salários por departamento" sem nenhuma ideia nova. Basta alterar o filtro para um intervalo.
Com DENSE_RANK, rnk <= 3 retorna os três níveis salariais distintos mais altos (possivelmente mais de três linhas em caso de empate). Com ROW_NUMBER, rn <= 3 retorna exatamente três linhas por departamento.
SELECT name, department_id, salary
FROM (
SELECT name, department_id, salary,
DENSE_RANK() OVER (
PARTITION BY department_id
ORDER BY salary DESC
) AS rnk
FROM employee
) t
WHERE rnk <= 3;Exemplo resolvido
Departamento 1: Ana 120, Bob 120, Cara 90. Departamento 2: Dan 200, Eve 150.
- DENSE_RANK = 1: Ana (120) e Bob (120) do departamento 1; Dan (200) do departamento 2. Três linhas.
- ROW_NUMBER = 1 com critério de desempate por identificador: um de Ana/Bob (o que tiver o menor identificador), além de Dan. Duas linhas.
Os mesmos dados produzem quantidades de linhas diferentes dependendo da função. Escolha de acordo com a pergunta.
Incluindo departamentos e fazendo a junção dos nomes
Os entrevistadores costumam adicionar uma tabela department e pedir o nome do departamento. Basta fazer a junção depois da classificação.
Mantenha a classificação na tabela employee e faça a junção com a tabela de consulta no final, para que o particionamento continue ocorrendo na granularidade correta.
SELECT d.name AS department, t.name AS employee, t.salary
FROM (
SELECT name, department_id, salary,
DENSE_RANK() OVER (
PARTITION BY department_id ORDER BY salary DESC
) AS rnk
FROM employee
) t
JOIN department d ON d.id = t.department_id
WHERE t.rnk = 1;Armadilhas a evitar
Erros comuns na classificação por grupo:
- Esquecer
PARTITION BYe fazer a classificação globalmente, retornando apenas o funcionário com o maior salário em toda a empresa. - Usar
ROW_NUMBERquando a pergunta implica que todos os empates devem aparecer, eliminando silenciosamente os funcionários empatados no topo. - Tentar colocar a função de janela diretamente em
WHERE, em vez de envolvê-la. - Fazer a junção com a tabela de departamentos antes da classificação e alterar acidentalmente a granularidade do particionamento.
Verificação rápida
Escolha a função de classificação correta para o requisito.
Recapitulação
O maior salário por departamento segue o padrão de classificação global mais PARTITION BY department_id:
- DENSE_RANK = 1 retorna todos os maiores salários empatados por departamento.
- ROW_NUMBER = 1 com um critério de desempate retorna exatamente um por departamento.
- Alternativas portáveis:
MAXcorrelacionado por departamento ou o máximo obtido comGROUP BYe associado novamente à tabela.
Para obter os N maiores, altere = 1 para <= N. Diga em voz alta como você decidiu tratar os empates.
Perguntas Frequentes
A aula “Maior salário por departamento” é grátis?
Sim — o texto completo de “Maior salário por departamento” é 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 “Maior salário por departamento”?
Combine particionamento e classificação para resolver problemas de maiores salários por grupo. 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 “Maior salário por departamento”?
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
- 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