Agregações por grupo sem GROUP BY
Use uma subconsulta correlacionada para calcular o máximo de um grupo junto às linhas detalhadas.
Agregações por grupo sem GROUP BY é 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.
O problema do detalhe com agregação
Uma pergunta clássica em entrevistas: "Mostre cada linha junto com uma agregação do seu grupo." Por exemplo, liste cada funcionário com o salário máximo do departamento na mesma linha.
Um GROUP BY simples reduz as linhas, portanto não consegue manter o detalhe por funcionário. Você precisa das linhas de detalhe e de um número no nível do grupo juntos.
Uma subconsulta correlacionada resolve isso de forma elegante: ela calcula a agregação do grupo para cada linha de detalhe sem reduzir nada.
Por que um GROUP BY simples falha aqui
Se você escrever SELECT dept_id, MAX(salary) FROM employees GROUP BY dept_id, obterá uma linha por departamento e perderá os nomes individuais.
Adicionar name ao SELECT sem adicioná-lo a GROUP BY gera o erro clássico "a coluna deve aparecer em GROUP BY".
O entrevistador verifica se você entende que GROUP BY reduz a cardinalidade. Para manter as linhas de detalhe, calcule a agregação de outra maneira.
Subconsulta correlacionada ao resgate
Coloque a agregação do grupo na lista de SELECT como uma subconsulta correlacionada. Cada linha de funcionário aciona um MAX interno com escopo definido pelo departamento desse funcionário.
A correlação e2.dept_id = e1.dept_id vincula a agregação ao grupo correto, enquanto a consulta externa ainda retorna uma linha por funcionário.
SELECT e1.name,
e1.dept_id,
e1.salary,
(SELECT MAX(e2.salary)
FROM employees e2
WHERE e2.dept_id = e1.dept_id) AS dept_max_salary
FROM employees e1;Comparando cada linha com seu grupo
Depois que a agregação do grupo estiver na consulta, você poderá comparar cada linha com ela. Uma pergunta frequente: "Encontre os funcionários que ganham acima da média do departamento."
Aqui, o AVG correlacionado está em WHERE, portanto cada funcionário é comparado com a média do próprio departamento.
SELECT e1.name, e1.dept_id, e1.salary
FROM employees e1
WHERE e1.salary > (
SELECT AVG(e2.salary)
FROM employees e2
WHERE e2.dept_id = e1.dept_id
);Calculando uma diferença em relação ao grupo
Você também pode mostrar o quanto cada linha se distancia da agregação do grupo. Subtrair a média correlacionada produz uma diferença por linha.
Observe que a mesma subconsulta correlacionada pode ser reutilizada em várias expressões de SELECT; o motor a avalia por linha cada vez que aparece.
SELECT e1.name,
e1.salary,
e1.salary - (SELECT AVG(e2.salary)
FROM employees e2
WHERE e2.dept_id = e1.dept_id) AS gap_from_dept_avg
FROM employees e1;Encontrando o maior salário por grupo
Para retornar apenas a pessoa mais bem paga por departamento, compare cada salário com o MAX correlacionado e mantenha as correspondências.
Esse padrão retorna empates: se dois funcionários compartilharem o máximo do departamento, ambos aparecerão. Esse comportamento no tratamento de empates costuma ser a pergunta de continuação do entrevistador.
SELECT e1.name, e1.dept_id, e1.salary
FROM employees e1
WHERE e1.salary = (
SELECT MAX(e2.salary)
FROM employees e2
WHERE e2.dept_id = e1.dept_id
);A alternativa com função de janela
O SQL moderno oferece uma ferramenta mais simples: funções de janela. MAX(salary) OVER (PARTITION BY dept_id) calcula a agregação do grupo sem reduzir as linhas e sem uma nova varredura correlacionada.
Os entrevistadores gostam quando você consegue apresentar as duas soluções e explicar que a versão com função de janela geralmente tem melhor desempenho porque percorre a tabela uma vez.
SELECT name,
dept_id,
salary,
MAX(salary) OVER (PARTITION BY dept_id) AS dept_max_salary
FROM employees;Diferenças entre subconsulta correlacionada e função de janela
As duas abordagens retornam a mesma estrutura, mas diferem:
- Subconsulta correlacionada: portátil, funciona em motores muito antigos, mas é reavaliada para cada linha.
- Função de janela: passagem única, muito mais rápida em tabelas grandes, exige suporte a funções de janela no SQL.
Diga qual você escolheria e por quê. Para uma execução pontual em uma tabela pequena, qualquer uma serve; para análises em grande escala, prefira a função de janela.
Exemplo resolvido: pedidos acima da média do cliente
Aplique o padrão aos pedidos. Mostre os pedidos cujo valor supera o valor médio dos pedidos feitos pelo próprio cliente.
O AVG correlacionado tem escopo definido por o2.customer_id = o1.customer_id, dando a cada pedido a base de referência individual de seu cliente.
SELECT o1.order_id, o1.customer_id, o1.amount
FROM orders o1
WHERE o1.amount > (
SELECT AVG(o2.amount)
FROM orders o2
WHERE o2.customer_id = o1.customer_id
);Observe os casos de NULL e de grupos vazios
Se um grupo tiver apenas uma linha, sua média será igual à dessa linha, então salary > avg será falso e a linha será descartada. Mencione esse caso extremo de forma proativa.
Além disso, salários NULL são ignorados por AVG e MAX, de acordo com a semântica das agregações do SQL. Se todo valor de um grupo for NULL, a agregação será NULL e as comparações se tornarão UNKNOWN, excluindo a linha. Antecipar esses casos é o que diferencia uma resposta completa.
Contando a posição dentro de um grupo
Você pode expressar a posição de uma linha dentro do grupo com um COUNT correlacionado. Para encontrar a posição salarial de cada funcionário dentro do departamento, conte quantos colegas ganham mais.
Posição 1 significa o maior salário. Adicionar 1 transforma a contagem de funcionários com salários maiores em uma posição começando em 1, e a correlação mantém o escopo no departamento.
SELECT e1.name,
e1.dept_id,
e1.salary,
(SELECT COUNT(*) + 1
FROM employees e2
WHERE e2.dept_id = e1.dept_id
AND e2.salary > e1.salary) AS salary_rank_in_dept
FROM employees e1;Verificação rápida
Escolha o motivo pelo qual uma subconsulta correlacionada é melhor que um GROUP BY simples para esta tarefa.
Recapitulação: agregações por grupo sem GROUP BY
Principais conclusões:
- Uma subconsulta correlacionada coloca uma agregação no nível do grupo em cada linha de detalhe sem reduzi-las.
- Use-a em SELECT para exibir a agregação ou em WHERE para comparar cada linha com seu grupo.
- O padrão
= MAX(...)retorna todas as linhas superiores empatadas. - Uma função de janela com
PARTITION BYfaz o mesmo em uma única passagem e geralmente se adapta melhor a grandes volumes.
Apresente as duas soluções e justifique sua escolha na entrevista.
Perguntas Frequentes
A aula “Agregações por grupo sem GROUP BY” é grátis?
Sim — o texto completo de “Agregações por grupo sem GROUP BY” é 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 “Agregações por grupo sem GROUP BY”?
Use uma subconsulta correlacionada para calcular o máximo de um grupo junto às linhas detalhadas. 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 “Agregações por grupo sem GROUP BY”?
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
- Anatomia de uma subconsulta correlacionada
- Agregações por grupo sem GROUP BY
- EXISTS e NOT EXISTS correlacionados
- Reescrevendo subconsultas correlacionadas como junções