Como Recuperar o Último Registro em Cada Grupo no SQL

Aprenda como recuperar o último registro de cada grupo em SQL com técnicas avançadas para MySQL, PostgreSQL, SQL Server e Oracle. Otimize consultas e melhore o desempenho do banco de dados agora!

Compartilhe:

Recuperar o último registro de cada grupo em um banco de dados é uma necessidade comum, mas que pode ser desafiadora dependendo do sistema de gerenciamento de banco de dados (SGDB) utilizado. Este artigo explora várias formas de resolver esse problema em diferentes SGDBs, como MySQL, PostgreSQL, SQL Server e Oracle, utilizando abordagens modernas e eficientes.


1. Entendendo o Problema

O objetivo é obter o último registro (ou o registro mais recente) de cada grupo baseado em uma ou mais colunas. Por exemplo, em uma tabela de vendas, você pode querer encontrar a venda mais recente de cada cliente.

Exemplo de Tabela:

idcliente_iddata_vendavalor
11012024-01-10200
21022024-01-15150
31012024-01-20300
41022024-01-22250

Resultado esperado: Queremos o último registro de cada cliente com base na coluna data_venda:

idcliente_iddata_vendavalor
31012024-01-20300
41022024-01-22250

2. Soluções Gerais

2.1 Usando ROW_NUMBER()

O uso da função ROW_NUMBER() é uma abordagem moderna e eficiente suportada por muitos SGDBs.

Exemplo (SQL Server, PostgreSQL, Oracle):

sqlCopiar códigoWITH cte AS (
    SELECT 
        id, 
        cliente_id, 
        data_venda, 
        valor,
        ROW_NUMBER() OVER (PARTITION BY cliente_id ORDER BY data_venda DESC) AS row_num
    FROM vendas
)
SELECT id, cliente_id, data_venda, valor
FROM cte
WHERE row_num = 1;

Como Funciona:

Abre em nova aba

  1. A função ROW_NUMBER()atribui um número a cada linha dentro de cada grupo (PARTITION BY cliente_id),ordenando por data_vendaem ordem decrescente.
  2. No passo final,filtramos apenas os registros onde row_num=1.

2.2 Usando DISTINCT ON

PostgreSQL oferece a funcionalidade DISTINCT ON,que é extremamente eficiente para este tipo de problema.

Exemplo (PostgreSQL):

sqlCopiar códigoSELECT DISTINCT ON (cliente_id) id,cliente_id,data_venda,valor
FROM vendas
ORDER BY cliente_id,data_venda DESC;

Como Funciona:

  1. DISTINCT ONretorna apenas o primeiro registro encontrado para cada grupo definido pela cláusula (cliente_id).
  2. A cláusula ORDER BYdetermina qual registro será considerado o “primeiro”para cada grupo.

2.3 Usando Subconsultas

Subconsultas correlacionadas funcionam em qualquer SGDB,incluindo MySQL.

Exemplo (MySQL,SQL Server,Oracle):

sqlCopiar códigoSELECT id,cliente_id,data_venda,valor
FROM vendas v1
WHERE data_venda=(SELECT MAX(data_venda)
FROM vendas v2
WHERE v1.cliente_id=v2.cliente_id);

Como Funciona:

  1. Para cada registro da tabela vendas,a subconsulta encontra a data máxima (MAX(data_venda)) para o mesmo cliente_id.
  2. Apenas os registros com a maior data_vendasão retornados.

Desvantagens:

  • Pode ser menos performático em tabelas grandes,já que a subconsulta é executada para cada linha.

2.4 Usando Funções de Agregação

Combinar GROUP BYcom funções de agregação pode ser uma abordagem simples.

Exemplo (MySQL,PostgreSQL,SQL Server):

sqlCopiar códigoSELECT v1.id,v1.cliente_id,v1.data_venda,v1.valor
FROM vendas v1
JOIN (SELECT cliente_id,MAX(data_venda) AS max_data
FROM vendas
GROUP BY cliente_id) v2
ON v1.cliente_id=v2.cliente_id AND v1.data_venda=v2.max_data;

Como Funciona:

  1. O subquery encontra a data máxima (MAX(data_venda) para cada cliente.
  2. O JOINcombina a tabela original com os resultados agregados para trazer os registros completos.

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.


3. Abordagens Específicas por SGDB

3.1 MySQL (Antes do 8.0)

MySQL antes da versão 8.0 não suportava funções analíticas como ROW_NUMBER(). Nesse caso,o uso de subconsultas ou agregações é necessário.

Exemplo:

sqlCopiar códigoSELECT v1.*
FROM vendas v1
INNER JOIN (SELECT cliente_id,MAX(data_venda) AS max_data
FROM vendas
GROUP BY cliente_id) v2
ON v1.cliente_id=v2.cliente_id AND v1.data_venda=v2.max_data;

3.2 MySQL 8.0 ou Superior

Com suporte a ROW_NUMBER():

sqlCopiar códigoWITH cte AS (SELECT id,cliente_id,data_venda,valor,ROW_NUMBER() OVER (PARTITION BY cliente_id ORDER BY data_venda DESC) AS row_num
FROM vendas)
SELECT id,cliente_id,data_venda,valor
FROM cte
WHERE row_num=1;

3.3 PostgreSQL

Usar DISTINCT ONé geralmente a abordagem mais eficiente:

sqlCopiar códigoSELECT DISTINCT ON (cliente_id) id,cliente_id,data_venda,valor
FROM vendas
ORDER BY cliente_id,data_venda DESC;

3.4 SQL Server

Usando ROW_NUMBER():

sqlCopiar códigoWITH cte AS (SELECT id,cliente_id,data_venda,valor,ROW_NUMBER() OVER (PARTITION BY cliente_id ORDER BY data_venda DESC) AS row_num
FROM vendas)
SELECT id,cliente_id,data_venda,valor
FROM cte
WHERE row_num=1;

3.5 Oracle

Com funções analíticas:

SELECT id,cliente_id,data_venda,valor
FROM (
SELECT
id,cliente_id,data_venda,valor,
ROW_NUMBER() OVER (PARTITION BY cliente_id ORDER BY data_venda DESC) AS row_num
FROM vendas
)
WHERE row_num=1;

4. Desempenho e Otimizações

4.1 Índices

  • Adicionar um índice nas colunas usadas para particionamento e ordenação (cliente_id,data_venda) pode melhorar significativamente o desempenho.

4.2 Tamanho da Tabela

  • Em tabelas muito grandes,preferir abordagens que minimizam leituras redundantes,como DISTINCT ON(PostgreSQL) ou ROW_NUMBER().

4.3 Benchmarking

  • Execute benchmarks em seu ambiente para comparar o desempenho de diferentes abordagens,especialmente se a tabela tiver milhões de registros.

5. Conclusão

Recuperar o último registro de cada grupo pode ser feito de várias formas,dependendo do SGDB e das necessidades específicas do sistema. Funções analíticas,como ROW_NUMBER(),são geralmente as mais eficientes e flexíveis,mas alternativas como DISTINCT ONe subconsultas também são úteis em cenários específicos. Entender as capacidades do SGDB escolhido e ajustar a abordagem para o contexto é essencial para garantir consultas rápidas e eficientes.

Referências Sobre o Tema

Aqui estão algumas referências confiáveis e úteis para aprofundar seu conhecimento sobre como recuperar o último registro em cada grupo em SQL:


Documentação Oficial

  1. MySQL:
  2. PostgreSQL:
  3. SQL Server:
  4. Oracle:

Livros

Para quem gosta de se aprofundar com leitura,livros oferecem uma visão mais técnica e estruturada.

Ambientes Práticos

A prática é essencial para dominar SQL. Aqui estão algumas ferramentas para experimentar e executar consultas.

VAI GOSTAR:

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.

RECENTES

Claude Sonnet 4.5: Mais Avançado para Programação e Automação

A Anthropic acaba de lançar o Claude Sonnet 4.5,...

AP2 do Google: Desenvolva Pagamentos para agentes de IA

O Google lançou o Agent Payments Protocol (AP2), um...

Curso gratuito de GitHub Copilot para devs e estudantes

A Microsoft abriu as inscrições para o primeiro Bootcamp...

Santander e a Alura oferecem 60.000 bolsas em carreira de tecnologia

Quer dar um salto na sua carreira? O Santander Imersão Digital está...

Google Tradutor desafia o Duolingo com novas ferramentas de aprendizagem de idiomas

O Google está lançando um novo recurso experimental com...

A peça que faltava para agentes de IA autônomos.

Este artigo foi originalmente publicado em: https://www.linkedin.com/newsletters/ezine-dev-ramos-da-inform%25C3%25A1tica-6947960536550526976/ A inteligência...
Newsletter semanal no LinkedIn
EZine Dev Ramos da Informática
Grandes dicas em JavaScript, Node, React, Next, Banco de Dados & IA.
Assinar grátis
Abre em nova aba
spot_img