No SQL, qual é a diferença entre count (coluna) e count (*)?


205

Eu tenho a seguinte consulta:

select column_name, count(column_name)
from table
group by column_name
having count(column_name) > 1;

Qual seria a diferença se eu substituísse todas as chamadas count(column_name)para count(*)?

Esta pergunta foi inspirada em Como encontro valores duplicados em uma tabela no Oracle? .


Para esclarecer a resposta aceita (e talvez minha pergunta), a substituição count(column_name)por count(*)retornaria uma linha extra no resultado que contém nullae a contagem de nullvalores na coluna.

Respostas:


235

count(*)conta NULLs e count(column)não

[edit] adicionou este código para que as pessoas possam executá-lo

create table #bla(id int,id2 int)
insert #bla values(null,null)
insert #bla values(1,null)
insert #bla values(null,1)
insert #bla values(1,null)
insert #bla values(null,1)
insert #bla values(1,null)
insert #bla values(null,null)

select count(*),count(id),count(id2)
from #bla

resultados 7 3 2


8
Apenas curioso: se você tiver uma linha com todos os NULLs, a contagem (*) ainda contará ou será apenas a contagem (coluna) para todas as colunas?
Joel Coehoorn

7
Esse padrão é aplicado aos DBMSs?
Eclipse

51
Vale ressaltar que, se você tiver uma coluna não anulável, como ID, a contagem (ID) melhorará significativamente o desempenho sobre a contagem (*).
tsilb

12
@tsilb: a resposta postada por @Alan afirma "count (*) é calculada observando os índices na tabela em questão e não as linhas de dados reais" que, se verdade, invalidam seu comentário. Entendo que @Alan pode estar errado, mas estou interessado na fonte de suas informações para descobrir qual é a correta.
6603 Tony

12
@tsilb: Muitos otimizadores de consulta modernos otimizarão a contagem (*) para usar índices quando for adequado.
Shannon Severance

37

Outra diferença menor, entre usar * e uma coluna específica, é que, no caso da coluna, você pode adicionar a palavra-chave DISTINCT e restringir a contagem a valores distintos:

select column_a, count(distinct column_b)
from table
group by column_a
having count(distinct column_b) > 1;

1
O grupo por coluna e o que está sendo contado devem ser diferentes? caso contrário, você teria nada a partir desta consulta
steevc

Sim, desculpe .. Eu não tinha notado que eles eram a mesma coluna no exemplo. Vou atualizar a postagem.
Brannon

16

Uma diferença adicional e talvez sutil é que, em algumas implementações de banco de dados, a contagem (*) é calculada observando os índices na tabela em questão, e não as linhas de dados reais. Como nenhuma coluna específica é especificada, não há necessidade de se preocupar com as linhas reais e seus valores (como seria se você contasse uma coluna específica). Permitir que o banco de dados use os dados do índice pode ser significativamente mais rápido do que fazê-lo contar linhas "reais".


5
+1 Sim, certamente verdadeiro para Oracle e PostgreSQL a partir de 9.2.
precisa

@DavidAldridge Você pode fornecer um ponteiro para a documentação (especialmente para o postgresql) onde isso é mencionado? Obrigado.
21819 Bhushan


10

A explicação nos documentos ajuda a explicar isso:

COUNT (*) retorna o número de itens em um grupo, incluindo valores NULL e duplicatas.

COUNT (expressão) avalia a expressão para cada linha de um grupo e retorna o número de valores não nulos.

Portanto, count (*) inclui valores nulos, o outro método não.


Para newbs SQL: A que arquivo de ajuda você está se referindo?
Bill o Lagarto

10

Podemos usar o Stack Exchange Data Explorer para ilustrar a diferença com uma simples consulta. A tabela Usuários no banco de dados do Stack Overflow possui colunas que geralmente são deixadas em branco, como o URL do site do usuário.

-- count(column_name) vs. count(*)
-- Illustrates the difference between counting a column
-- that can hold null values, a  'not null' column, and  count(*)

select count(WebsiteUrl), count(Id), count(*) from Users

Se você executar a consulta acima no Data Explorer , verá que a contagem é a mesma count(Id)e count(*)porque a Idcoluna não permite nullvalores. A WebsiteUrlcontagem é muito menor, no entanto, porque essa coluna permite null.


2

Basicamente, a COUNT(*)função retorna todas as linhas de uma tabela, enquanto COUNT(COLUMN_NAME)isso não ocorre; isto é, exclui valores nulos que todos aqui também responderam aqui. Mas a parte mais interessante é tornar as consultas e o banco de dados otimizados; é melhor usá- COUNT(*)lo, a menos que faça várias contagens ou uma consulta complexa em vez de COUNT(COLUMN_NAME). Caso contrário, ele realmente diminuirá o desempenho do seu banco de dados enquanto lida com um grande número de dados.


1
  • A frase COUNT (*) indica que o SQL Server retornará todas as linhas de uma tabela, incluindo NULLs.
  • COUNT (nome_da_coluna) apenas recupera as linhas com um valor não nulo nas linhas.

Consulte o código a seguir para execuções de teste do SQL Server 2008:

-- Variable table
DECLARE @Table TABLE
(
      CustomerId int NULL 
    , Name nvarchar(50) NULL
)

-- Insert some records for tests
INSERT INTO @Table VALUES( NULL, 'Pedro')
INSERT INTO @Table VALUES( 1, 'Juan')
INSERT INTO @Table VALUES( 2, 'Pablo')
INSERT INTO @Table VALUES( 3, 'Marcelo')
INSERT INTO @Table VALUES( NULL, 'Leonardo')
INSERT INTO @Table VALUES( 4, 'Ignacio')

-- Get all the collumns by indicating *
SELECT  COUNT(*) AS 'AllRowsCount'
FROM    @Table

-- Get only content columns ( exluce NULLs )
SELECT  COUNT(CustomerId) AS 'OnlyNotNullCounts'
FROM    @Table

1

COUNT(*) - Retorna o número total de registros em uma tabela (incluindo registros com valor NULL).

COUNT(Column Name) - Retorna o número total de registros não nulos. Isso significa que ignora a contagem de registros com valor NULL nessa coluna específica.


0

É melhor usar

Count(1) in place of column name or * 

para contar o número de linhas em uma tabela, é mais rápido do que qualquer formato, pois nunca verifica o nome da coluna na tabela existente ou não


4
Incorreto para Oracle, pelo menos, e para outros RDBMS também, eu suspeito. A contagem interna (1) é transformada em contagem (*). Em particular, o desempenho da contagem (*) não é afetado negativamente pelo tamanho das linhas, o que é um equívoco comum.
David Aldridge

Isso é verdade para o SQL Server. Como @Ali Adravi disse, COUNT(*)em comparação com COUNT(columnName)não irá verificar o valor da coluna, porque apenas enumera linhas. Mas COUNT(columnName)é mais lento, mesmo o countaplicado em uma idcoluna! Pelo menos no SQL Server, é claro.
ABS

0

Não há diferença se uma coluna for corrigida em sua tabela, se você quiser usar mais de uma coluna do que precisar especificar quantas colunas você precisa contar ......

Obrigado,


0

Conforme mencionado nas respostas anteriores, Count(*)conta mesmo as NULLcolunas, enquanto count(Columnname)conta apenas se a coluna tiver valores.

É sempre melhor prática para evitar *( Select *, count *...)


Não é de todo uma prática recomendada evitarCOUNT(*)
David Faber
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.