Voltar para a lista de artigos Artigos
9 minutos de leitura

Qual é a diferença entre COUNT(*), COUNT(1), COUNT(nome da coluna) e COUNT(DISTINCT nome da coluna)?

Você já notou que existem diferentes variações da função SQL COUNT()? Este artigo explica os vários argumentos e seus usos.

Como usuário do SQL, você provavelmente já está familiarizado com a função COUNT(). Mesmo sendo relativamente simples, ela pode ser usada de várias maneiras. Cada forma tem uma finalidade bem diferente. Você já deve ter visto algum código com a função COUNT(*) ou COUNT(1). Você provavelmente também já viu alguns outros usos da função COUNT(), tais como COUNT(nome da coluna) e COUNT(DISTINCT nome da coluna), mesmo que não os tenha usado.

Você deve estar se perguntando o que cada variação de COUNT() faz. Vamos descobrir!

Antes de continuar, aviso que neste artigo usarei a função GROUP BY, mas de uma forma muito simples. Se você precisar refrescar sua memória sobre o uso dela, aqui está um artigo que explica a sintaxe e os princípios gerais de GROUP BY. Você também pode aprender os fundamentos sobre a função GROUP BY em nosso curso interativo SQL para Iniciantes. Ele contém mais de 100 exercícios práticos, para te deixar mais confiante em suas habilidades de SQL a medida que você avançar pelos conteúdos.

Como COUNT() Funciona?

Como você pode imaginar, a função COUNT() faz contagens. Mas o que exatamente ela conta? A função COUNT() pertence às funções de agregação do SQL. Ela conta o número de linhas que satisfazem os critérios definidos em parênteses. Ela não retorna as linhas em si, e sim mostra o número de linhas que atendem aos seus critérios.

Por falar em funções de agregação, elas são extremamente úteis em relatórios SQL. Se você quiser saber mais sobre o assunto, há muitas funções de agregação e "GROUP BY" em nosso curso Como Criar Relatórios Básicos em SQL .

Agora, de volta à contagem. Obviamente, existem coisas diferentes que podem ser contadas. É por isso que existem diferentes variações da função COUNT(). Neste artigo, vou focar em quatro delas:

  • COUNT(*)
  • COUNT(1)
  • COUNT(nome da coluna)
  • COUNT(DISTINCT nome da coluna)

COUNT(*) vs COUNT(1)

Você deve ter visto várias discussões sobre as diferenças entre COUNT(*) e COUNT(1) e, ao tentar encontrar a resposta, é possível que tudo tenha ficado ainda mais confuso. Existe, afinal, alguma diferença? A resposta simples é não - não há diferença.

A função COUNT(*) conta o total de linhas na tabela, incluindo os valores NULL. A semântica para COUNT(1) é um pouquinho diferente; discutiremos isso mais adiante. Entretanto, os resultados para COUNT(*) e COUNT(1) são idênticos.

Vamos testar esta afirmação usando uma consulta de exemplo. Suponha que eu tenha uma tabela chamada encomendas que contém estas colunas:

  • id_pedido: O ID do pedido.
  • id_cliente: O ID do cliente que fez o pedido.
  • valor_pedido: O valor total dos itens encomendados, em reais.
  • data_pagamento: Quando o pedido foi pago pelo cliente.

Se eu quisesse contar o número de linhas em toda a tabela, usaria a função COUNT() da seguinte maneira:

SELECT COUNT(*) AS numero_linhas
FROM encomendas;

Como você vê, eu usei a função COUNT(*). O resultado aparecerá na nova coluna numero_linhas:

numero_linhas
8

Ok, mas e se em vez disso eu usasse COUNT(1)? Aqui está:

SELECT COUNT(1) AS numero_linhas
FROM encomendas;

O código é essencialmente o mesmo. A única diferença é que eu usei COUNT(1) em vez de COUNT(*). E o resultado? Ele retorna o mesmo número de linhas:

numero_linhas
8

Existe um equívoco comum de que o "1" em COUNT(1) significa "contar os valores na primeira coluna e retornar o número de linhas". Desse equívoco segue um segundo: que COUNT(1) é mais rápido porque contará apenas a primeira coluna, enquanto COUNT(*) usará toda a tabela para chegar ao mesmo resultado.

Isto não é verdade. O número entre parênteses não significa o número da coluna na tabela. Se você colocar qualquer número entre parênteses, garanto-lhe que o resultado será o mesmo. Quer uma prova? Aqui está:

SELECT COUNT(-13) AS numero_linhas
FROM encomendas;

Se o primeiro equívoco fosse verdadeiro, o código acima significaria que eu gostaria de contar o número de linhas na -13ª coluna. Há apenas quatro colunas na tabela encomendas e portanto, não existe uma 13ª coluna. Com certeza, também não existe uma coluna -13, o que quer que isso signifique. Que tal conferirmos o resultado do código? Como era de se esperar:

numero_linhas
8

Mais uma vez, o resultado é o mesmo. Então, o que significa o valor entre parênteses de COUNT()? É o valor que a função COUNT() atribuirá à cada linha da tabela. A função então contará quantas vezes o asterisco (*) ou (1) ou (-13) foi atribuído. Naturalmente, será atribuído um número de vezes igual ao número de linhas na tabela. Em outras palavras, COUNT(1) atribui o valor do parênteses (número 1, neste caso) a cada linha da tabela, então a mesma função conta quantas vezes o valor do parênteses (1, no nosso caso) foi atribuído; naturalmente, isto será sempre igual ao número de linhas da tabela. Os parênteses podem conter qualquer valor, a única coisa que não vai funcionar será deixá-los vazios.

Vamos tentar algo simples. Em vez de um número, coloque o seguinte valor entre parênteses: "serão sempre oito linhas". Aqui está o código:

SELECT COUNT('serão sempre oito linhas') AS numero_linhas
FROM encomendas;

Execute o código e... Surpresa! São realmente oito linhas:

numero_linhas
8

Como não importa qual valor você coloca entre parênteses, COUNT(*) e COUNT(1) são exatamente iguais. Eles são exatamente iguais porque o valor entre parênteses COUNT() serve apenas para dizer à consulta o que ela vai contar.

Se estas declarações são exatamente iguais, então não há diferença no desempenho. Não pense que, aqui, o asterisco (*) tem o mesmo uso que na declaração SELECT *. Não, COUNT(*) não passará por toda a tabela antes de retornar o número de linhas e, assim, não é mais lento que COUNT(1).

Então, no final, quem vence a disputa COUNT(*) vs. COUNT(1)? Ninguém - é um empate, pois são exatamente iguais. Entretanto, eu recomendo usar COUNT(*), a forma mais comum. Ele também é menos confuso, o que significa que outros usuários de SQL entenderão que a função contará todos o número de linhas da tabela, incluindo os valores NULL.

COUNT(*) vs COUNT(nome da coluna)

E em relação a COUNT(*) vs COUNT(coluna nome), existe alguma diferença? Com certeza!

Como você já aprendeu, COUNT(*) contará todas as linhas da tabela, incluindo os valores NULL. Por outro lado, COUNT(nome da coluna) contará todas as linhas da coluna especificada, excluindo os valores NULL.

Como você já sabe, há oito linhas na tabela encomendas. Vamos ver quantas linhas haverá quando eu utilizar a coluna id_pedido para a contagem (imaginando que eu quero ver quantos pedidos foram feitos). Mais uma vez obteremos oito linhas, certo? Vamos testar:

SELECT COUNT(id_pedido) AS numero_pedidos
FROM encomendas;

O resultado foi o mesmo? Não! Há sete pedidos, e não oito.

numero_pedidos
7

Isso significa que algo deu errado? Não! Na verdade, existem apenas sete pedidos com um id_pedido; uma linha tem um NULL ao invés de um id_pedido. Abaixo está a linha que faz a diferença:

id_pedidoid_clientepreco_pedidodata_pedido
NULLCL0921327.85NULL

Lembre-se sempre: COUNT(nome da coluna) só contará linhas onde a coluna dada NÃO for um valor NULL.

Vamos fazer algo interessante agora e combinar ambas as variações do COUNT() em uma única consulta. Suponha que eu queira ver a identificação do cliente com o número total de pedidos feitos por esse cliente. Também quero mostrar o número total de pedidos pagos por aquele cliente (pedidos pagos não têm um valor NULL na coluna data_pagamento.) Eis como eu o faria:

SELECT	id_cliente,
		COUNT(*) AS numero_pedidos,
		COUNT(data_pagamento) AS numero_pedidos_pagos
FROM encomendas
GROUP BY id_cliente;

A consulta primeiro calculará o número total de pedidos usando COUNT(*) - ou seja, incluirá os valores de NULL. Depois, a parte COUNT (data_pagamento) AS numero_pedidos_pagos contará as linhas da coluna data_pagamento que são NOT NULL. Quero os resultados para cada cliente, por isso agrupei o resultado pela coluna id_cliente. Aqui está o que eu recebo:

id_clientenumero_pedidosnumero_pedidos_pagos
CL01211
CL04911
CL05222
CL09210
CL10822
CL14911

Você pode ver que a diferença acontece para o cliente CL092.

Os princípios de combinação GROUP BY e COUNT() são explicados neste artigo sobre as funções de agregação GROUP BY no SQL. Se você quiser praticar mais, confira estes cinco exemplos de GROUP BY.

COUNT() nos permite usar expressões, assim como nomes de colunas, como argumento. Você sabe como encontrar o número de pedidos acima de 1.000 reais usando apenas a função COUNT()? Veja como a seguir:

SELECT COUNT(CASE WHEN preco_pedido > 1000 THEN 1 END) 
AS encomendas_significativas
FROM encomendas;

Ao invés de colocar condições no final da consulta e filtrar após a função COUNT() fazer seu trabalho, podemos usar a declaração CASE. Foi o que eu fiz na consulta acima. É usada como uma declaração IF-THEN-ELSE. CASE é seguida pela condição, que é definida pelas declarações WHEN e THEN. Também pode haver uma declaração ELSE, mas ela não é necessária neste caso, pois quero apenas contar o número de valores, e não nos valores em si. Toda declaração CASE termina com a declaração END.

A declaração COUNT() acima diz o seguinte:

  1. Encontre todos os valores na coluna preco_pedido acima de 1.000.
  2. Atribua o valor 1 (você pode atribuir qualquer valor que quiser) a estes valores.
  3. Atribua NULL a linhas com preços abaixo de 1.000.
  4. Conte o número de 1s atribuídos.
  5. Mostre o resultado na coluna encomendas_significativas.

E aqui está o resultado:

encomendas_significativas
5

COUNT(nome da coluna) vs COUNT(DISTINCT nome da coluna)

Você provavelmente consegue imaginar qual é a diferença entre essas duas versões de COUNT(). COUNT(nome_da_coluna) incluirá valores duplicados ao contar. Por outro lado, COUNT (DISTINCT nome da coluna) contará apenas linhas distintas (únicas) na coluna definida.

Se você quiser contar o número de clientes que fizeram um pedido, COUNT (nome da coluna) pode funcionar. Vamos testar este código simples:

SELECT COUNT (id_cliente) AS numero_clientes
FROM encomendas;

Você já conhece o processo, pois já usei a função COUNT(nome da coluna). Desta vez, ela conta todas as linhas da coluna id_cliente, com o resultado sendo mostrado na coluna numero_clientes. Aqui está o resultado:

numero_clientes
8

Vamos conferir o resultado, olhando para toda a tabela encomendas:

id_pedidoid_clientepreco_pedidodata_pedido
OR2020-01CL108154872020-01-08
OR2020-28CL149154872020-01-14
OR2020-12CL10812549.222020-01-09
OR2020-91CL012542.55NULL
NULLCL0921327.85NULL
OR2020-112CL049150002020-02-28
OR2020-213CL0521502020-03-12
OR2020-213CL0522002020-03-12

Existem oito linhas, mas será que este é mesmo o número de clientes? Observe que os clientes CL108 e CL052 aparecem duas vezes. Se eu quiser saber o número real de clientes, preciso contar cada cliente apenas uma vez. Como posso fazer isso? Utilizando COUNT(DISTINCT id_cliente):

SELECT COUNT(DISTINCT id_cliente) AS numero_clientes
FROM encomendas;

Esta consulta também contará as linhas na coluna id_cliente, mas contará cada cliente apenas uma vez. Isto ocorre devido à palavra-chave DISTINCT. Dê uma olhada no resultado:

numero_clientes
6

Este é o resultado correto; existem realmente apenas seis clientes únicos.

Será que você consegue contar usando COUNT()?

Agora que você entende várias variações comuns da função COUNT(), você pode criar cálculos e relatórios mais complexos. COUNT() é uma das funções de agregação mais utilizadas, por isso é essencial que você entenda bem as variações de COUNT() e como elas são usadas. Se você tiver dúvidas sobre alguma das variações da função COUNT() que discutimos neste artigo, deixe um comentário! Terei o maior prazer em ajudar. E, para mais práticas usando COUNT(), experimente nosso curso Como Criar Relatórios Básicos em SQL .