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.

Bill the Lizard
fonte

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

SQLMenace
fonte
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;
Brannon
fonte
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".

Alan
fonte
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
@Bhushan, aqui está você, wiki.postgresql.org/wiki/Index-only_scans
David Aldridge
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.

Peter C
fonte
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.

Bill the Lizard
fonte
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.

Ahmedul Kabir
fonte
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
G21
fonte
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.

Arun Salomão
fonte
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

Ali Adravi
fonte
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,

Hiren gardhariya
fonte
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 *...)

Unna
fonte
Não é de todo uma prática recomendada evitarCOUNT(*)
David Faber