Was ist in SQL der Unterschied zwischen count (Spalte) und count (*)?

204

Ich habe folgende Frage:

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

Was wäre der Unterschied , wenn ich alle Anrufe ersetzt count(column_name)zu count(*)?

Diese Frage wurde inspiriert von Wie finde ich doppelte Werte in einer Tabelle in Oracle? .


Um die akzeptierte Antwort (und möglicherweise meine Frage) zu verdeutlichen, würde das Ersetzen count(column_name)durch count(*)eine zusätzliche Zeile im Ergebnis zurückgeben, die a nullund die Anzahl der nullWerte in der Spalte enthält.

Bill die Eidechse
quelle

Antworten:

234

count(*)zählt NULL und count(column)nicht

[edit] hat diesen Code hinzugefügt, damit die Leute ihn ausführen können

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

Ergebnisse 7 3 2

SQLMenace
quelle
8
Nur neugierig: Wenn Sie eine Zeile mit allen NULL-Werten haben, würde count (*) sie immer noch zählen, oder ist nur count (column) für alle Spalten?
Joel Coehoorn
7
Gilt dieser Standard für DBMS?
Eclipse
51
Es ist erwähnenswert, dass count (ID) die Leistung gegenüber count (*) erheblich verbessert, wenn Sie eine nicht nullfähige Spalte wie ID haben.
Tsilb
12
@tsilb: Die von @Alan gepostete Antwort "count (*) wird berechnet, indem die Indizes in der betreffenden Tabelle und nicht die tatsächlichen Datenzeilen betrachtet werden", was Ihren Kommentar ungültig macht, wenn dies zutrifft. Ich schätze, dass @Alan möglicherweise falsch ist, aber ich bin an der Quelle Ihrer Informationen interessiert, um herauszufinden, welche richtig ist.
Tony
12
@tsilb: Viele moderne Abfrageoptimierer optimieren count (*), um Indizes zu verwenden, wenn dies sinnvoll ist.
Shannon Severance
37

Ein weiterer kleiner Unterschied zwischen der Verwendung von * und einer bestimmten Spalte besteht darin, dass Sie im Spaltenfall das Schlüsselwort DISTINCT hinzufügen und die Anzahl auf bestimmte Werte beschränken können:

select column_a, count(distinct column_b)
from table
group by column_a
having count(distinct column_b) > 1;
Brannon
quelle
1
Sollte die Gruppe nach Spalte und die gezählte unterschiedlich sein? Andernfalls würden Sie nichts von dieser Abfrage erhalten
steevc
Ja, Entschuldigung. Ich hatte nicht bemerkt, dass es sich im Beispiel um dieselbe Spalte handelt. Ich werde den Beitrag aktualisieren.
Brannon
16

Ein weiterer und möglicherweise subtiler Unterschied besteht darin, dass in einigen Datenbankimplementierungen die Anzahl (*) berechnet wird, indem die Indizes für die betreffende Tabelle und nicht die tatsächlichen Datenzeilen betrachtet werden. Da keine bestimmte Spalte angegeben ist, müssen Sie sich nicht mit den tatsächlichen Zeilen und ihren Werten befassen (wie dies der Fall wäre, wenn Sie eine bestimmte Spalte gezählt hätten). Das Zulassen, dass die Datenbank die Indexdaten verwendet, kann erheblich schneller sein als das Zählen von "echten" Zeilen.

Alan
quelle
5
+1 Ja, sicherlich wahr für Oracle und für PostgreSQL ab 9.2.
David Aldridge
@DavidAldridge Können Sie einen Zeiger auf die Dokumentation (insbesondere für postgresql) bereitstellen, in der dies erwähnt wird? Vielen Dank.
Bhushan
@ Bhushan hier geht's wiki.postgresql.org/wiki/Index-only_scans
David Aldridge
10

Die Erklärung in den Dokumenten hilft, dies zu erklären:

COUNT (*) gibt die Anzahl der Elemente in einer Gruppe zurück, einschließlich NULL-Werten und Duplikaten.

COUNT (Ausdruck) wertet den Ausdruck für jede Zeile in einer Gruppe aus und gibt die Anzahl der Nicht-Null-Werte zurück.

Count (*) enthält also Nullen, die andere Methode nicht.

Peter C.
quelle
Für SQL-Neulinge: Auf welche Hilfedatei beziehen Sie sich?
Bill the Lizard
10

Wir können den Stack Exchange Data Explorer verwenden , um den Unterschied mit einer einfachen Abfrage zu veranschaulichen. Die Benutzertabelle in der Datenbank von Stack Overflow enthält Spalten, die häufig leer bleiben, z. B. die Website-URL des Benutzers.

-- 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

Wenn Sie die obige Abfrage im Daten-Explorer ausführen , sehen Sie, dass die Anzahl für count(Id)und count(*)weil die IdSpalte keine nullWerte zulässt , gleich ist. Die WebsiteUrlAnzahl ist jedoch viel niedriger, da diese Spalte dies zulässt null.

Bill die Eidechse
quelle
2

Grundsätzlich gibt die COUNT(*)Funktion alle Zeilen aus einer Tabelle zurück, während COUNT(COLUMN_NAME)dies nicht der Fall ist. das heißt, es schließt Nullwerte aus, die alle hier auch hier beantwortet haben. Am interessantesten ist es jedoch, Abfragen und Datenbanken zu optimieren. Es ist besser, sie zu verwenden, es COUNT(*)sei denn, Sie führen mehrere Zählungen oder eine komplexe Abfrage durch COUNT(COLUMN_NAME). Andernfalls wird die DB-Leistung beim Umgang mit einer großen Anzahl von Daten erheblich verringert.

Ahmedul Kabir
quelle
1
  • Der Satz COUNT (*) gibt an, dass SQL Server alle Zeilen aus einer Tabelle einschließlich NULL zurückgeben soll.
  • COUNT (Spaltenname) ruft nur die Zeilen mit einem Wert ungleich Null in den Zeilen ab.

Informationen zu Testausführungen von SQL Server 2008 finden Sie im folgenden Code:

-- 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
quelle
1

COUNT(*) - Gibt die Gesamtzahl der Datensätze in einer Tabelle zurück (einschließlich Datensätze mit NULL-Werten).

COUNT(Column Name) - Gibt die Gesamtzahl der Nicht-NULL-Datensätze zurück. Dies bedeutet, dass das Zählen von NULL-Datensätzen in dieser bestimmten Spalte ignoriert wird.

Arun Solomon
quelle
0

Es ist am besten zu verwenden

Count(1) in place of column name or * 

Um die Anzahl der Zeilen in einer Tabelle zu zählen, ist es schneller als jedes andere Format, da nie überprüft wird, ob der Spaltenname in der Tabelle vorhanden ist oder nicht

Ali Adravi
quelle
4
Zumindest für Oracle und auch für andere RDBMS falsch, vermute ich. Intern wird count (1) in count (*) umgewandelt. Insbesondere wird die Leistung von count (*) nicht durch die Größe der Zeilen beeinträchtigt, was ein häufiges Missverständnis ist.
David Aldridge
Dies gilt für SQL Server. Wie @Ali Adravi sagte, wird COUNT(*)im Vergleich zu COUNT(columnName)nicht der Spaltenwert überprüft, da nur Zeilen aufgelistet werden. Ist COUNT(columnName)aber langsamer auch das countauf eine idSäule angewendete ! Zumindest in SQL Server natürlich.
ABS
0

Es gibt keinen Unterschied, ob eine Spalte in Ihrer Tabelle fixiert ist. Wenn Sie mehr als eine Spalte verwenden möchten, müssen Sie angeben, wie viele Spalten Sie zählen müssen.

Vielen Dank,

Hiren Gardhariya
quelle
0

Wie in den vorherigen Antworten erwähnt, Count(*)zählt sogar die NULLSpalte, während count(Columnname)nur zählt, wenn die Spalte Werte hat.

Es ist immer am beste Praxis zu vermeiden *( Select *, count *, ...)

Unna
quelle
Es ist überhaupt keine bewährte Methode zu vermeidenCOUNT(*)
David Faber