In SQL, qual è la differenza tra count (colonna) e count (*)?


205

Ho la seguente domanda:

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

Quale sarebbe la differenza se sostituissi tutte le chiamate count(column_name)a count(*)?

Questa domanda è stata ispirata da Come posso trovare valori duplicati in una tabella in Oracle? .


Per chiarire la risposta accettata (e forse la mia domanda), la sostituzione count(column_name)con count(*)restituisce una riga aggiuntiva nel risultato che contiene nullae il conteggio dei nullvalori nella colonna.

Risposte:


235

count(*)conta NULL e count(column)non lo fa

[modifica] ha aggiunto questo codice in modo che le persone possano eseguirlo

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

risultati 7 3 2


8
Solo curioso: se hai una riga con tutti i NULL, conteresti (*) continui a contarla, o è solo count (colonna) per tutte le colonne?
Joel Coehoorn,

7
Questo è lo standard nei DBMS?
Eclipse,

51
Vale la pena ricordare che se si dispone di una colonna non nullable come ID, il conteggio (ID) migliorerà significativamente le prestazioni rispetto al conteggio (*).
Tsilb,

12
@tsilb: la risposta pubblicata da @Alan afferma che "count (*) viene calcolato osservando gli indici nella tabella in questione anziché le righe di dati effettivi" che, se vero, invalida il tuo commento. Apprezzo che @Alan possa essere sbagliato, ma sono interessato alla fonte delle tue informazioni per scoprire quale è corretto.
Tony

12
@tsilb: molti moderni ottimizzatori di query ottimizzeranno il conteggio (*) per utilizzare gli indici quando ha senso.
Shannon Severance,

37

Un'altra differenza minore, tra l'utilizzo di * e una colonna specifica, è che nel caso della colonna è possibile aggiungere la parola chiave DISTINCT e limitare il conteggio a valori distinti:

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

1
Il gruppo per colonna e quello contato dovrebbero essere diversi? altrimenti non
otterresti

Sì, scusa .. Non avevo notato che erano la stessa colonna nell'esempio. Aggiornerò il post.
Brannon,

16

Un'ulteriore e forse sottile differenza è che in alcune implementazioni di database il conteggio (*) viene calcolato osservando gli indici sulla tabella in questione anziché le righe di dati effettive. Poiché non viene specificata alcuna colonna specifica, non è necessario preoccuparsi delle righe effettive e dei loro valori (come sarebbe se si contasse una colonna specifica). Consentire al database di utilizzare i dati dell'indice può essere significativamente più veloce rispetto al conteggio delle righe "reali".


5
+1 Sì, sicuramente vero per Oracle e per PostgreSQL dal 9.2 in poi.
David Aldridge,

@DavidAldridge Puoi fornire un puntatore alla documentazione (specialmente per postgresql) dove questo è menzionato? Grazie.
Bhushan,


10

La spiegazione nei documenti aiuta a spiegare questo:

COUNT (*) restituisce il numero di elementi in un gruppo, inclusi valori NULL e duplicati.

COUNT (espressione) valuta l'espressione per ogni riga in un gruppo e restituisce il numero di valori non nulli.

Quindi count (*) include valori null, l'altro metodo no.


Per i principianti SQL: a quale file della guida ti riferisci?
Bill the Lizard,

10

Possiamo usare Stack Exchange Data Explorer per illustrare la differenza con una semplice query. La tabella Users nel database di Stack Overflow ha colonne che vengono spesso lasciate vuote, come l'URL del sito Web dell'utente.

-- 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 esegui la query sopra in Esplora dati , vedrai che il conteggio è lo stesso per count(Id)e count(*)perché la Idcolonna non consente i nullvalori. Il WebsiteUrlconteggio è molto più basso, però, perché quella colonna lo consente null.


2

Fondamentalmente la COUNT(*)funzione restituisce tutte le righe da una tabella mentre COUNT(COLUMN_NAME)non lo fa; cioè esclude valori nulli a cui anche tutti qui hanno risposto qui. Ma la parte più interessante è rendere le query e il database ottimizzati che è meglio usare a COUNT(*)meno che non si eseguano conteggi multipli o query complesse anziché COUNT(COLUMN_NAME). Altrimenti, ridurrà davvero le prestazioni del tuo DB mentre gestisci un numero enorme di dati.


1
  • La frase COUNT (*) indica che SQL Server restituisce tutte le righe da una tabella, inclusi i NULL.
  • COUNT (nome_colonna) recupera solo le righe con un valore non nullo nelle righe.

Vedere il codice seguente per le esecuzioni di test 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(*) - Restituisce il numero totale di record in una tabella (inclusi i record con valore NULL).

COUNT(Column Name) - Restituisce il numero totale di record non NULL. Significa che ignora il conteggio dei record con valore NULL in quella particolare colonna.


0

È meglio usare

Count(1) in place of column name or * 

per contare il numero di righe in una tabella, è più veloce di qualsiasi formato perché non va mai a controllare che il nome della colonna nella tabella esista o meno


4
Sospetto almeno errato per Oracle e anche per altri RDBMS. Il conteggio interno (1) viene trasformato in conteggio (*). In particolare, le prestazioni del conteggio (*) non sono influenzate negativamente dalla dimensione delle righe, che è un malinteso comune.
David Aldridge,

Questo è vero per SQL Server. Come ha detto @Ali Adravi, COUNT(*)in confronto con COUNT(columnName)non andrà a controllare il valore della colonna, perché elenca solo le righe. Ma COUNT(columnName)è più lento anche l' countapplicazione su una idcolonna! Almeno in SQL Server, ovviamente.
ABS,

0

Non c'è alcuna differenza se una colonna è corretta nella tua tabella, se vuoi usare più di una colonna di quanto devi specificare quante colonne hai richiesto di contare ......

Grazie,


0

Come menzionato nelle risposte precedenti, Count(*)conta anche le NULLcolonne, mentre count(Columnname)conta solo se la colonna ha valori.

E 'sempre buona norma evitare di *( Select *, count *, ...)


Non è affatto una buona pratica da evitareCOUNT(*)
David Faber,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.