Ramos da InformáticaBanco de DadosSQL DISTINCT e GROUP BY: Guia Real de Soluções

SQL DISTINCT e GROUP BY: Guia Real de Soluções

-

Este artigo tem como objetivo mostrar as diferenças entre DISTINCT e GROUP BY no SQL com exemplos práticos.

Para descrever as diferenças entre DISTINCT e GROUP BY no SQL, vamos inicialmente recorrer à um exemplo da documentação oficial, inicialmente do a instrução SQL DISTINCT:

 

Dica de Leitura: Se você está procurando entender melhor como otimizar suas consultas SQL além do uso de DISTINCT e GROUP BY, é importante também conhecer as diferenças entre funções e procedures. Um artigo que pode ajudar a esclarecer essas dúvidas é o SQL – Diferenças Entre Funções e Procedures, que oferece uma visão detalhada sobre esses conceitos essenciais em bancos de dados.

SELECT [ ALL | DISTINCT ]  
[ TOP ( expression ) [ PERCENT ] [ WITH TIES ] ]   
<select_list>  

ALL
Especifica que linhas duplicadas podem aparecer no conjunto de resultados. 
ALL é o padrão.
DISTINCT
Especifica que só linhas exclusivas podem aparecer no conjunto de resultados. 
Valores nulos são considerados iguais para os propósitos
da palavra-chave DISTINCT.

O par de colchetes no trecho [ ALL | DISTINCT ] indica que os dois argumentos são opcionais e que se informados são mutuamente exclusivos, isto é, ou um ou outro. Como consta na documentação o argumento ALL é o padrão, ou seja, se nenhum dos argumentos constar do comando, assume-se a presença de ALL. A respeito do argumento DISTINCT a documentação cita linhas exclusivas, entende-se por valores não repetidos.

A definição de <select_list> é extensa mas, para fins deste artigo, somente será considerada a presença de nomes de colunas:

SELECT coluna_1, coluna_2, ..., coluna_n
  from tabela;

Agora um exemplo baseado em GROUP BY:
GROUP BY {
      <column-expression>  
    | ROLLUP ( <group_by_expression> [ ,...n ] )  
    | CUBE ( <group_by_expression> [ ,...n ] )  
    | GROUPING SETS ( <grouping_set> [ ,...n ]  )  
    | () 
} [ ,...n ]

Agrupa um conjunto de linhas selecionadas em um conjunto de linhas de resumo pelos valores de uma ou mais colunas ou expressões. Uma linha é retornada para cada grupo. As funções de agregação na lista de <seleção> da cláusula SELECT fornecem informações sobre cada grupo em vez de linhas individuais.

O objetivo dessa cláusula é agrupar linhas em que existam mesmos valores para as colunas definidas na cláusula, gerando subconjuntos. Para cada subconjunto podem então serem executadas funções de agregação nas demais colunas. Ao final, para cada subconjunto é retornada uma única linha, contendo as colunas de agrupamento e os resultados das funções de agregação. Para a definição de <column_expression> iremos considerar somente nomes de colunas.

SQL: Funções de agregação

Na documentação de GROUP BY consta funções de agregação. Ao consultar a documentação a respeito de funções de agregação, temos

As funções de agregação executam um cálculo em um conjunto de valores e retornam um único valor. As funções de agregação normalmente são usadas com a cláusula GROUP BY da instrução SELECT.

Em um modelo simples, as funções de agregação que constem na cláusula SELECT são executadas para cada subconjunto gerado pela cláusula GROUP BY.

Curso Banco de Dados

Como exemplos de função de agregação temos:

COUNT: Retorna o número de itens em um grupo.
AVG: Retorna a média dos valores em um grupo.
SUM: Retorna a soma de uma expressão numérica avaliada em um conjunto especificado.

Demonstração de aplicação dos recursos

Para demonstrar a aplicação de DISTINCT e de GROUP BY, utilizaremos a seguinte tabela:

-- código #1
CREATE TABLE Vendas (
  NomeVendedor varchar(30),
  ProdutoVendido varchar(50),
  QuantidadeVendida integer,
  ValorVenda money
);

INSERT

-- código #2
INSERT into VENDAS values
    ('João', 'Macarrão', 18, 35.00),
    ('Maria', 'Beterraba', 3, 12.00),
    ('José', 'Cenoura', 5, 5.00),
    ('João', 'Molho de tomate', 1, 7.50),
    ('Antônio', 'Beterraba', 4, 16.00),
    ('João', 'Macarrão', 3, 4.20);

E você precise gerar os seguintes relatórios:

  • Quais são os vendedores?
  • Quais produtos cada vendedor vendeu?
  • Qual o total de vendas, em reais, de cada vendedor?
  • Qual a quantidade de itens vendidos de cada produto, por vendedor?
  • Quantos produtos diferentes foram vendidos por cada vendedor?

Quais são os vendedores?

-- código #3
SELECT NomeVendedor 
  from VENDAS;

João
Maria
José
João
Antônio
João

Entretanto, percebe que o nome João aparece 3 vezes. Como eliminar as repetições? É uma aplicação típica do uso de DISTINCT!

-- código #3a
SELECT DISTINCT NomeVendedor 
  from VENDAS;

Antônio
João
José
Maria

Ao analisar os planos de execução dos códigos #3 e #3a, percebe-se facilmente a diferença: A presença do operador lógico DISTINCT SORT no plano de execução relativo ao código #3a.

exemplo SQL DISTINC SORT

EXEMPLO SELECT COM DISTINCT NO SQL SERVER

Quais produtos cada vendedor vendeu?

Essa requisição envolve o uso de duas colunas: NomeVendedor e ProdutoVendido.

-- código #5
SELECT NomeVendedor, ProdutoVendido 
  from VENDAS;

No resultado percebe-se que o par {João, Macarrão} aparece mais de uma vez. Eis outra aplicação típica do uso de DISTINCT, mas agora atuando sobre duas colunas.

-- código #5a
SELECT DISTINCT NomeVendedor, ProdutoVendido 
  from VENDAS;

Importante: DISTINCT atua simultaneamente nas colunas NomeVendedor e ProdutoVendido . Considera as duas colunas para eliminar as repetições.

Qual o total de vendas em reais de cada vendedor?

Para atender a esta solicitação será necessário somar o conteúdo da coluna ValorVenda para cada vendedor. Ou seja, será necessário primeiro separar as vendas por vendedor (gerando um subconjunto com as linhas de cada vendedor) e a seguir realizar a soma de cada subconjunto.

VAI GOSTAR:

Como aprender a programar, um guia definitivo 

21 comandos SQL essenciais e avançados e conteúdos extras

Maneiras de aprender SQL e banco de dados online (de graça!)

Eis uma aplicação típica da cláusula de agrupamento GROUP BY.

Para agrupar as linhas por vendedor utilizamos

GROUP BY NomeVendedor

E para somar as vendas, utilizamos a função de agregação SUM

Sum(ValorVenda)

Código

-- código #6
SELECT NomeVendedor, SUM(ValorVenda) 
  from Vendas
  group by NomeVendedor;

Antônio 16,00
João 46,70
José 5,00
Maria 12,00

Este é o primeiro código deste artigo com a cláusula GROUP BY. Analisando o plano de execução do código #6, percebe-se algo que não constava nos planos de execução anteriores, que é o operador Stream Aggregate.

EXEMPLO SELECT COM GROUP BY E Stream Aggregate

Conforme documentação do operador Stream aggregate, agrupa linhas através de uma ou mais colunas e em seguida calcula uma ou mais expressões de agregação retornadas pela consulta.

O operador Stream Aggregate requer a entrada de dados ordenada pelas colunas dentro de seus grupos. Para garantir essa condição, o otimizador de consultas acrescenta um operador Sort antes deste operador (se os dados ainda não estiverem classificados). Isto pode ser observado no plano de execução acima, pois a tabela Vendas é do tipo heap e sem qualquer índice.

Quantos itens de cada produto foram vendidos por vendedor?

Para atender a essa solicitação será necessário criar subconjuntos por vendedor e dentro de cada um desses subconjuntos, criar subconjuntos por produto. Isto é possível pois a cláusula GROUP BY permite a definição de mais de uma coluna. Para agrupar as linhas por vendedor utilizamos

GROUP BY NomeVendedor

Para agrupar cada produto dentro de cada subconjunto, acrescentamos a coluna que identifica o produto

GROUP BY NomeVendedor, ProdutoVendido

E para somar a quantidade de itens vendidos utilizamos novamente a função de agregação SUM

   Sum(QuantidadeVendida)

Código:

-- código #7
SELECT NomeVendedor, ProdutoVendido, sum (QuantidadeVendida)
  from Vendas
  group by NomeVendedor, ProdutoVendido;

Antônio Beterraba 4
Maria Beterraba 3
José Cenoura 5
João Macarrão 21
João Molho de Tomate 1

Quantos produtos diferentes foram vendidos por cada vendedor?

Para contar quantos produtos diferentes foram vendidos por cada vendedor a função de agregação COUNT é a ideal

-- código #8
SELECT NomeVendedor, count (ProdutoVendido)
  from Vendas
  group by NomeVendedor;

Antonio 1
João 3
José 1
Maria 1

Ao consultar o resultado, e comparar com o conteúdo da tabela de Vendas, percebemos que para o Vendedor João foram contabilizados 3 produtos quando ele somente vendeu dois tipos de produtos: Macarrão e Molho de tomate. Mas ele fez duas vendas de macarrão. Como fazer para que a função de agregação COUNT somente some uma vez cada produto? A resposta está no uso de DISTINCTdentro do parâmetro da função, conforme

COUNT ( { [ [ ALL | DISTINCT ] expression ] | * } )


-- código #8a
SELECT NomeVendedor, count (distinct ProdutoVendido)
  from Vendas
group by NomeVendedor;

Antonio 1
João 2
José 1
Maria 1

Agora sim o resultado veio correto, com o vendedor João contabilizando 2 produtos diferentes.

E como ficaram os planos de execução dos códigos #8 e #8a?

SELECT COM DISTINCT E AGREGGATE E COUNT NO SQL SERVER

Percebe-se em ambos a presença do operador Stream Aggregate devido à cláusula GROUP BY. E na segunda consulta, referente ao código #8a a presença do operador lógico DISTINCT SORT, antes de realizar o agrupamento. Este operador lógico foi incluído pelo otimizador de consultas para processar DISTINCT ProdutoVendido.


GROUP BY no lugar de DISTINCT

Quando a cláusula GROUP BY é utilizada sem que exista função de agregação na cláusula SELECT, ela possui efeito semelhante a de DISTINCT.

Por exemplo, o código #3a pode ser reescrito, substituindo DISTINCT por GROUP BY:

-- código #3a
SELECT DISTINCT NomeVendedor 
  from Vendas;


-- código #9
SELECT NomeVendedor
  from Vendas
  group by NomeVendedor;
 

O retorno do código #9 é

Antônio
João
José
Maria

O plano de execução é o seguinte:

GROUP BY no lugar de DISTINCT EM SQL

Considerações parciais sobre o uso de DISTINCT e GROUP BY

A pergunta deste tópico serviu de base para escrever artigo sobre o assunto. No item de referências ao final há o link para o artigo completo.

Neste texto a tabela Vendas é do tipo heap e sem índices nonclustered. Optou-se por esse tipo para demonstração do funcionamento conceitual de GROUP BY e DISTINCT pois a presença de índices pode alterar o plano de execução gerado.

Google Cloud apresenta novas ferramentas de IA para varejistas

DISTINCT e GROUP BY não fazem a mesma coisa, possuem objetivos diferentes e normalmente geram planos de execução diferentes.

Há exceções.


Referências

Documentação

  1. Cláusula SELECT
  2. Eliminando duplicatas com DISTINCT
  3. GROUP BY
  4. Funções de agregação
  5. Sum()
  6. Count()
  7. Operador Stream Aggregate
  8. Operador Sort

Artigo completo em inglês

VOCÊ ESTÁ NA SEÇÃO BANCO DE DADOS.

LEIA TAMBÉM:


✦ Recomendação do Editor

Eleve o seu nível no assunto

Se você está procurando aprender mais sobre como otimizar suas consultas SQL após ler nosso artigo sobre o SQL DISTINCT e GROUP BY, eu recomendo procurar por cursos de especialização em SQL Eficiente.

Com um curso de especialização em SQL Eficiente, você vai adquirir habilidades práticas para resolver problemas complexos de consultas SQL, otimizar o desempenho de seus bancos de dados e tomar decisões informadas com dados precisos. Isso vai dar uma visão mais completa e profunda da gerência de dados e ajudá-lo a crescer na carreira como profissional de tecnologia.



Ver ofertas em destaque na Amazon


Ajude a manter este projeto, a Ramos da Informática pode ganhar uma comissão sobre as vendas qualificadas.
Ramos da Informática
Ramos da Informáticahttps://ramosdainformatica.com.br
Ramos da Informática é um hub de comunidade dedicado a linguagens de programação, banco de dados, DevOps, Internet das Coisas (IoT), tecnologias da Indústria 4.0, cibersegurança e startups. Com curadoria de conteúdos de qualidade, o projeto é mantido por Ramos de Souza Janones.

Mais recentes

Como aprender a programar, um guia definitivo

Última atualização em 23/04/2026. Guia completo sobre: Como aprender a programar. Espero que este “guia” ou “manifesto”, como prefiro chamar, seja...

Stream Deck para Desenvolvedores: o Console de Comando do Futuro

Esqueça os streamers. Descubra como o Stream Deck se tornou o hardware essencial para Engenheiros de IA e Full...

Como Usar o Skills in Chrome no Brasil: Tutorial Completo de IA

A inteligência artificial já faz parte do nosso fluxo de trabalho, mas ter que reescrever os mesmos prompts repetidamente...

Context Engineering: Como Arquitetar Dados para LLMs e RAG

Na edição desta newsletter intitulada “Engenharia de Prompt: Não é só mais uma buzzword“: https://www.linkedin.com/pulse/engenharia-de-prompt-n%C3%A3o-%C3%A9-s%C3%B3-mais-uma-buzzword-de-souza-janones-tpkxf tratei sobre o tema...
E-Zine Dev

Evolua para Sênior

Estratégias de Node.js, arquitetura Limpa e IA que nunca publicamos no blog. Junte-se a +10.000 devs.

Assinar Gratuitamente Zero spam. Cancele quando quiser.

Aprender Idiomas com Google Tradutor: Na Prática

O Google está lançando um novo recurso experimental com tecnologia de IA no Google Tradutor, projetado para ajudar as...

Comunidades Internacionais de Desenvolvedores

Descubra as melhores comunidades internacionais de devs para 2026: GitHub, Stack Overflow, Discord e mais. Comparativo de salários Brasil vs. exterior e guia de carreira remota.

Mais Lidos

Como Usar o Skills in Chrome no Brasil: Tutorial Completo de IA

A inteligência artificial já faz parte do nosso fluxo...

GraphRAG: Como Superar os Limites do RAG com Grafos

Este artigo foi originalmente publicado em: https://www.linkedin.com/newsletters/ezine-dev-ramos-da-inform%25C3%25A1tica-6947960536550526976/ A inteligência artificial...

O Que é Account Abstraction? O Futuro dos Pagamentos na Web3

Entenda o que é Account Abstraction (EIP-4337) no Ethereum....

Aceleração de Fintech: Práticas Efetivas para Crescimento Rápido

Está aberta a segunda edição do Next, um dos...
E-Zine Dev

Evolua para Sênior

Estratégias de Node.js, arquitetura Limpa e IA que nunca publicamos no blog. Junte-se a +10.000 devs.

Assinar Gratuitamente Zero spam. Cancele quando quiser.

Você vai gostarrelacionados
Continue aprendendo

E-Zine Dev Ramos

Quer dominar arquitetura e IA?

Junte-se a +10.000 profissionais. Receba semanalmente estratégias de Node.js, React e IA que nunca publicamos no blog.

Assinar Gratuitamente Zero spam. Cancele quando quiser.