Como Selecionar Linhas com o Maior Valor em uma Coluna no SQL

Aprenda como selecionar linhas com o maior valor em uma coluna no SQL. Descubra técnicas como subconsultas, funções de janela, e junções para otimizar suas consultas e resolver problemas comuns de banco de dados.

Compartilhe:

Ao trabalhar com bases de dados relacionais, uma tarefa comum é selecionar linhas de uma tabela que contenham o maior valor em uma determinada coluna, respeitando condições específicas. Embora a tarefa pareça simples à primeira vista, as nuances da linguagem SQL e as diferenças entre bancos de dados tornam o problema mais interessante.

Este artigo aborda o tema em detalhes, explicando os conceitos envolvidos, apresentando diferentes abordagens para resolver o problema e analisando suas vantagens e desvantagens. Além disso, veremos exemplos práticos para diferentes bancos de dados, como MySQL, PostgreSQL, SQL Server e Oracle.

O Problema

Imagine que você tenha uma tabela chamada sales com as seguintes colunas e dados:

idsalespersonamount
1Alice500
2Bob300
3Alice700
4Bob600
5Charlie400

Nosso objetivo é selecionar a linha de cada salesperson onde o amount é o maior.

Resultado Esperado

Para o exemplo acima, queremos o seguinte resultado:

idsalespersonamount
3Alice700
4Bob600
5Charlie400

A lógica é simples: para cada vendedor (salesperson), selecione a linha com o maior valor de amount.

Conceitos-Chave

Antes de mergulharmos nas soluções, é importante entender os seguintes conceitos em SQL:

Apoie a Ramos da Informática

Café com Deus Pai Vol. 6 - 2026: Porções Diárias de Amor oferece 365 mensagens diárias que convidam você a um encontro íntimo com Deus, fortalecendo a fé e nutrindo a alma.

👉 Confira na Amazon .
Nas compras você contribui para manter o site no ar.

Certificado MEC

Domine Bancos de Dados como um
Engenheiro de Dados de Elite

SQL, NoSQL, BigQuery, Databricks, SSIS + Python
Saia do zero e conquiste R$11.000/mês em 6 meses.
200h+ de projetos reais com ferramentas do Google, Amazon e Netflix.

Garanta Sua Vaga com 7 Dias de Garantia

  1. Funções Agregadas:
    • A função MAX() é usada para determinar o maior valor em uma coluna. No entanto, ela sozinha não é suficiente para retornar a linha associada a esse valor.
  2. Agrupamento (GROUP BY):
    • Permite agrupar linhas com valores compartilhados em colunas específicas.
  3. Junções (JOIN):
    • Podem ser usadas para combinar tabelas ou subconjuntos da mesma tabela, resolvendo problemas onde precisamos comparar linhas.
  4. Subconsultas:
    • Subconsultas permitem que você execute uma consulta dentro de outra, geralmente para filtrar ou agregar resultados.
  5. CTEs (Common Table Expressions):
    • Disponíveis em bancos modernos, como PostgreSQL e SQL Server, ajudam a organizar consultas complexas.

Soluções Comuns

1. Subconsulta Simples com MAX()

A abordagem mais básica envolve uma subconsulta para determinar o maior valor de amount por vendedor e, em seguida, selecionar as linhas correspondentes.

SELECT id, salesperson, amount
FROM sales s1
WHERE amount = (
SELECT MAX(amount)
FROM sales s2
WHERE s1.salesperson = s2.salesperson
);

Explicação:

  1. Para cada linha da tabela sales (representada por s1), verificamos o maior valor de amount para aquele salesperson usando uma subconsulta (s2).
  2. Apenas as linhas onde amount corresponde ao valor máximo são retornadas.

Vantagens:

  • Simples de entender e implementar.
  • Funciona em praticamente todos os bancos de dados.

Desvantagens:

  • Pode ser ineficiente em tabelas grandes, pois a subconsulta é executada para cada linha.

2. Usando ROW_NUMBER() ou RANK() (Bancos Avançados)

Bancos de dados modernos oferecem funções de janela, como ROW_NUMBER() e RANK(), que permitem numerar as linhas com base em critérios específicos.

WITH RankedSales AS (
SELECT id, salesperson, amount,
ROW_NUMBER() OVER (PARTITION BY salesperson ORDER BY amount DESC) AS rank
FROM sales
)
SELECT id, salesperson, amount
FROM RankedSales
WHERE rank = 1;

Explicação:

  1. Criamos uma CTE chamada RankedSales onde numeramos as linhas de cada salesperson com base no valor de amount em ordem decrescente.
  2. Apenas as linhas com rank = 1 (maior valor) são selecionadas.

Vantagens:

  • Mais eficiente do que subconsultas em muitos casos.
  • Suporta empates ao usar RANK() (ex.: se dois vendedores tiverem o mesmo valor máximo).

Desvantagens:

  • Não está disponível em bancos mais antigos, como versões antigas do MySQL.

3. Junção com Subconsulta Agregada

Outra abordagem comum envolve calcular o valor máximo em uma subconsulta e, em seguida, unir os resultados com a tabela original.

SELECT s.id, s.salesperson, s.amount
FROM sales s
JOIN (
SELECT salesperson, MAX(amount) AS max_amount
FROM sales
GROUP BY salesperson
) max_sales
ON s.salesperson = max_sales.salesperson AND s.amount = max_sales.max_amount;

Explicação:

  1. Na subconsulta, agrupamos por salesperson e calculamos o valor máximo de amount.
  2. A tabela resultante (max_sales) é unida com a tabela original (sales) para retornar as linhas correspondentes.

Vantagens:

  • Boa performance em bancos que otimizam junções.
  • Fácil de entender.

Desvantagens:

  • Mais código do que as soluções anteriores.

SQL: Selecionando Somente Linhas com o Maior Valor em uma Coluna

Ao trabalhar com bases de dados relacionais, uma tarefa comum é selecionar linhas de uma tabela que contenham o maior valor em uma determinada coluna, respeitando condições específicas. Embora a tarefa pareça simples à primeira vista, as nuances da linguagem SQL e as diferenças entre bancos de dados tornam o problema mais interessante.

VAI GOSTAR: O que é normalização de banco de dados? – Descubra tudo sobre a normalização de banco de dados, incluindo as explicações detalhadas da 5NF e 2NF com exemplos práticos. Aprenda como melhorar a organização e a eficiência dos seus dados e otimize seus sistemas de forma profissional.

Este artigo aborda o tema em detalhes, explicando os conceitos envolvidos, apresentando diferentes abordagens para resolver o problema e analisando suas vantagens e desvantagens. Além disso, veremos exemplos práticos para diferentes bancos de dados, como MySQL, PostgreSQL, SQL Server e Oracle.


O Problema

Imagine que você tenha uma tabela chamada sales com as seguintes colunas e dados:

idsalespersonamount
1Alice500
2Bob300
3Alice700
4Bob600
5Charlie400

Nosso objetivo é selecionar a linha de cada salesperson onde o amount é o maior.

Resultado Esperado

Para o exemplo acima, queremos o seguinte resultado:

idsalespersonamount
3Alice700
4Bob600
5Charlie400

A lógica é simples: para cada vendedor (salesperson), selecione a linha com o maior valor de amount.


Conceitos-Chave

Antes de mergulharmos nas soluções, é importante entender os seguintes conceitos em SQL:

  1. Funções Agregadas:
    • A função MAX() é usada para determinar o maior valor em uma coluna. No entanto, ela sozinha não é suficiente para retornar a linha associada a esse valor.
  2. Agrupamento (GROUP BY):
    • Permite agrupar linhas com valores compartilhados em colunas específicas.
  3. Junções (JOIN):
    • Podem ser usadas para combinar tabelas ou subconjuntos da mesma tabela, resolvendo problemas onde precisamos comparar linhas.
  4. Subconsultas:
    • Subconsultas permitem que você execute uma consulta dentro de outra, geralmente para filtrar ou agregar resultados.
  5. CTEs (Common Table Expressions):
    • Disponíveis em bancos modernos, como PostgreSQL e SQL Server, ajudam a organizar consultas complexas.

Soluções Comuns

1. Subconsulta Simples com MAX()

A abordagem mais básica envolve uma subconsulta para determinar o maior valor de amount por vendedor e, em seguida, selecionar as linhas correspondentes.

sqlCopiar códigoSELECT id, salesperson, amount
FROM sales s1
WHERE amount = (
    SELECT MAX(amount)
    FROM sales s2
    WHERE s1.salesperson = s2.salesperson
);

Explicação:

  1. Para cada linha da tabela sales (representada por s1), verificamos o maior valor de amount para aquele salesperson usando uma subconsulta (s2).
  2. Apenas as linhas onde amount corresponde ao valor máximo são retornadas.

Vantagens:

  • Simples de entender e implementar.
  • Funciona em praticamente todos os bancos de dados.

Desvantagens:

  • Pode ser ineficiente em tabelas grandes, pois a subconsulta é executada para cada linha.

2. Usando ROW_NUMBER() ou RANK() (Bancos Avançados)

Bancos de dados modernos oferecem funções de janela, como ROW_NUMBER() e RANK(), que permitem numerar as linhas com base em critérios específicos.

sqlCopiar códigoWITH RankedSales AS (
    SELECT id, salesperson, amount,
           ROW_NUMBER() OVER (PARTITION BY salesperson ORDER BY amount DESC) AS rank
    FROM sales
)
SELECT id, salesperson, amount
FROM RankedSales
WHERE rank = 1;

Explicação:

  1. Criamos uma CTE chamada RankedSales onde numeramos as linhas de cada salesperson com base no valor de amount em ordem decrescente.
  2. Apenas as linhas com rank = 1 (maior valor) são selecionadas.

Vantagens:

  • Mais eficiente do que subconsultas em muitos casos.
  • Suporta empates ao usar RANK() (ex.: se dois vendedores tiverem o mesmo valor máximo).

Desvantagens:

  • Não está disponível em bancos mais antigos, como versões antigas do MySQL.

3. Junção com Subconsulta Agregada

Outra abordagem comum envolve calcular o valor máximo em uma subconsulta e, em seguida, unir os resultados com a tabela original.

sqlCopiar códigoSELECT s.id, s.salesperson, s.amount
FROM sales s
JOIN (
    SELECT salesperson, MAX(amount) AS max_amount
    FROM sales
    GROUP BY salesperson
) max_sales
ON s.salesperson = max_sales.salesperson AND s.amount = max_sales.max_amount;

Explicação:

  1. Na subconsulta, agrupamos por salesperson e calculamos o valor máximo de amount.
  2. A tabela resultante (max_sales) é unida com a tabela original (sales) para retornar as linhas correspondentes.

Vantagens:

  • Boa performance em bancos que otimizam junções.
  • Fácil de entender.

Desvantagens:

  • Mais código do que as soluções anteriores.

4. Solução Específica para MySQL (Antes da Versão 8.0)

Antes da versão 8.0, o MySQL não suportava funções de janela, mas ainda era possível obter o resultado usando truques como auto-junções.

SELECT s1.id, s1.salesperson, s1.amount
FROM sales s1
LEFT JOIN sales s2
ON s1.salesperson = s2.salesperson AND s1.amount < s2.amount
WHERE s2.id IS NULL;

Explicação:

  1. Fazemos uma junção onde s1.amount é menor que s2.amount.
  2. Apenas as linhas de s1 sem correspondências (s2.id IS NULL) são retornadas, indicando que são as maiores para aquele salesperson.

Vantagens:

  • Funciona em versões antigas do MySQL.

Desvantagens:

  • Complexidade maior do que as outras abordagens.

Desafios e Considerações

1. Linhas Empatadas

Se dois vendedores tiverem o mesmo valor máximo, algumas abordagens podem retornar apenas uma das linhas. Para incluir todas, substituímos ROW_NUMBER() por RANK() ou ajustamos as junções.

WITH RankedSales AS (
SELECT id, salesperson, amount,
RANK() OVER (PARTITION BY salesperson ORDER BY amount DESC) AS rank
FROM sales
)
SELECT id, salesperson, amount
FROM RankedSales
WHERE rank = 1;

2. Indexação

Para tabelas grandes, indexar as colunas usadas em agrupamentos ou filtros (salesperson e amount) melhora significativamente o desempenho.

3. Cenários de Uso

  • Relatórios: Mostrar o melhor desempenho de cada vendedor.
  • Auditorias: Identificar transações mais altas em categorias específicas.
  • Ranking: Construir sistemas de pontuação ou classificações.

Conclusão

Selecionar linhas com o maior valor em uma coluna é uma tarefa essencial, mas cheia de nuances. A solução ideal depende do banco de dados usado, do tamanho da tabela e dos requisitos específicos do problema.

Em resumo:

  • Subconsultas: Simples, mas potencialmente menos eficientes.
  • Funções de Janela: Modernas e poderosas, ideais para bancos avançados.
  • Junções: Flexíveis e eficazes em muitos casos.

A escolha da abordagem correta pode fazer uma grande diferença em termos de legibilidade, eficiência e escalabilidade. Agora que você entende os princípios e estratégias, está pronto para aplicar esses conceitos nos seus próprios projetos!

Aqui estão algumas referências úteis para o artigo sobre como selecionar linhas com o maior valor em uma coluna no SQL:

Referências Técnicas e Documentação

  1. Documentação Oficial dos Bancos de Dados:
  2. Funções de Janela:
  3. SQL Joins e Subconsultas:

Apoie a Ramos da Informática

Café com Deus Pai Vol. 6 - 2026: Porções Diárias de Amor oferece 365 mensagens diárias que convidam você a um encontro íntimo com Deus, fortalecendo a fé e nutrindo a alma.

👉 Confira na Amazon .
Nas compras você contribui para manter o site no ar.

Compartilhe:

Ramos da Informática
Ramos da Informáticahttps://ramosdainformatica.com.br
Ramos da Informática é um hub de comunidade sobre linguagens de programação, banco de dados, DevOps, Internet das Coisas, tecnologia da indústria 4.0, Cyber Segurança e Startups.
🔥 Oferta Gamer

NITRO V15

Poder Total em Suas Mãos

N
🚀
Processador
Ryzen 7 7735HS
🎮
GPU
RTX 4050 6GB
RAM + SSD
16GB + 512GB
🖥️
Tela
15.6" FHD 165Hz
Ray Tracing DLSS 3.0 DDR5 Wi-Fi 6 RGB Backlit
Confira na Amazon
OFERTA!
Ver na Amazon
✓ Entrega Rápida ✓ Garantia