In SQL Server is de COUNT()
functie retourneert het aantal items dat in een groep is gevonden. Je kunt het gebruiken om erachter te komen hoeveel rijen er in een tabel of resultatenset zitten.
Syntaxis
De syntaxis gaat als volgt:
-- Aggregation Function Syntax COUNT ( { [ [ ALL | DISTINCT ] expression ] | * } ) -- Analytic Function Syntax COUNT ( [ ALL ] { expression | * } ) OVER ( [] )
ALL
past de aggregatiefunctie toe op alle waarden. Dit is de standaardwaarde.
DISTINCT
specificeert dat de functie het aantal unieke niet-null-waarden retourneert.
expression
is een uitdrukking van elk type, behalve afbeelding , ntekst , of tekst . Geaggregeerde functies en subquery's worden niet ondersteund in de expressie.
*
geeft aan dat alle rijen moeten worden geteld en geretourneerd, inclusief dubbele rijen en rijen die null-waarden bevatten. COUNT(*)
neemt geen parameters en ondersteunt het gebruik van DISTINCT
. niet . Het vereist ook geen uitdrukking parameter (omdat het geen informatie over een bepaalde kolom gebruikt).
OVER ( [ <partition_by_clause> ]
verdeelt de resultatenset geproduceerd door de FROM
clausule in partities waarop de functie wordt toegepast. Indien niet gespecificeerd, behandelt de functie alle rijen van de queryresultatenset als een enkele groep.
Voorbeeld 1 – Basisgebruik
Hier is een eenvoudig voorbeeld dat laat zien hoe deze functie werkt:
SELECT COUNT(*) AS 'Row Count' FROM Artists;
Resultaat:
+-------------+ | Row Count | |-------------| | 16 | +-------------+
In dit geval zijn er 16 rijen in de Artiesten tafel.
Voor de zekerheid, hier zijn ze:
SELECT * FROM Artists;
Resultaat:
+------------+------------------------+--------------+-------------+ | ArtistId | ArtistName | ActiveFrom | CountryId | |------------+------------------------+--------------+-------------| | 1 | Iron Maiden | 1975-12-25 | NULL | | 2 | AC/DC | 1973-01-11 | NULL | | 3 | Allan Holdsworth | 1969-01-01 | NULL | | 4 | Buddy Rich | 1919-01-01 | NULL | | 5 | Devin Townsend | 1993-01-01 | NULL | | 6 | Jim Reeves | 1948-01-01 | NULL | | 7 | Tom Jones | 1963-01-01 | NULL | | 8 | Maroon 5 | 1994-01-01 | NULL | | 9 | The Script | 2001-01-01 | NULL | | 10 | Lit | 1988-06-26 | NULL | | 11 | Black Sabbath | 1968-01-01 | NULL | | 12 | Michael Learns to Rock | 1988-03-15 | NULL | | 13 | Carabao | 1981-01-01 | NULL | | 14 | Karnivool | 1997-01-01 | NULL | | 15 | Birds of Tokyo | 2004-01-01 | NULL | | 16 | Bodyjar | 1990-01-01 | NULL | +------------+------------------------+--------------+-------------+
Zoals verwacht worden 16 rijen geretourneerd.
Merk op dat de CountryId kolom bevat niets anders dan null-waarden. Dit is handig voor het volgende voorbeeld.
Voorbeeld 2 – Specificeer een kolom
In het vorige voorbeeld werd een asterisk gebruikt (*
) om alle rijen op te geven. Dit resulteert erin dat alle rijen worden geteld, ongeacht of er duplicaten zijn of dat er null-waarden zijn.
U kunt ook een bepaalde kolom specificeren. Wanneer u dit doet, worden null-waarden niet meegeteld. Dat wil zeggen, alle rijen die een null-waarde voor die kolom bevatten, worden niet meegeteld.
Hier is een voorbeeld met de CountryId kolom zoals vermeld in het vorige voorbeeld:
SELECT COUNT(CountryId) AS 'Row Count' FROM Artists;
Resultaat:
+-------------+ | Row Count | |-------------| | 0 | +-------------+
Zoals we in het vorige voorbeeld zagen, zijn alle rijen voor deze kolom NULL
. Daarom is het resulterende aantal rijen nul.
Laten we wat waarden aan die kolom toevoegen:
UPDATE Artists SET CountryId = 2 WHERE ArtistName IN ( 'AC/DC', 'Karnivool', 'Birds of Tokyo', 'Bodyjar' );
Laten we nu de rijen voor die kolom opnieuw tellen:
SELECT COUNT(CountryId) AS 'Row Count' FROM Artists;
Resultaat:
+-------------+ | Row Count | |-------------| | 4 | +-------------+
Voorbeeld 3 – Met DISTINCT
Dit voorbeeld gebruikt de DISTINCT
clausule om alleen afzonderlijke rijen te retourneren (d.w.z. niet-duplicaten).
In het vorige voorbeeld heb ik de tabel bijgewerkt zodat dezelfde
CountryId
werd toegepast op vier artiesten (ik gebruikte SET CountryId = 2
voor alle vier de artiesten). Dit resulteerde in vier rijen met dezelfde
CountryId
.
Dit is wat er gebeurt als ik tel hoeveel verschillende CountryId s staan in die tabel:
SELECT COUNT(DISTINCT CountryId) 'Distinct CountryIds' FROM Artists;
Resultaat:
+-----------------------+ | Distinct CountryIds | |-----------------------| | 1 | +-----------------------+
Dit is te verwachten, want hoewel er vier rijen zijn met een CountryId , het is nog steeds maar één duidelijk CountryId .
Laten we het voor de zekerheid naast de "niet-onderscheidende" versie uitvoeren:
SELECT COUNT(CountryId) 'Non Distinct', COUNT(DISTINCT CountryId) 'Distinct' FROM Artists;
Resultaat:
+----------------+------------+ | Non Distinct | Distinct | |----------------+------------| | 4 | 1 | +----------------+------------+
Dus de niet-onderscheiden versie laat zien hoe vaak de
CountryId
verschijnt in de tabel, terwijl de DISTINCT
versie telt meerdere keren als 1.
Laten we nog een CountryId toevoegen naar de tafel:
UPDATE Artists SET CountryId = 1 WHERE ArtistName = 'Carabao';
En voer de query nu opnieuw uit:
SELECT COUNT(CountryId) 'Non Distinct', COUNT(DISTINCT CountryId) 'Distinct' FROM Artists;
Resultaat:
+----------------+------------+ | Non Distinct | Distinct | |----------------+------------| | 5 | 2 | +----------------+------------+
Voorbeeld 4 – Gebruik een WHERE-clausule
Hier is een snel voorbeeld met een WHERE
clausule.
SELECT COUNT(*) AS 'Row Count' FROM Artists WHERE ActiveFrom >= '2000-01-01';
Resultaat:
+-------------+ | Row Count | |-------------| | 2 | +-------------+
Voorbeeld 5 – Met GROUP BY
Hier is een voorbeeld van het groeperen van de artiesten in één kolom en het tellen van alle albums voor elke artiest in de andere kolom.
Voorbeeld:
SELECT ArtistName, COUNT(al.AlbumId) 'Number of Albums' FROM Artists ar INNER JOIN Albums al ON al.ArtistId = ar.ArtistId GROUP BY ArtistName ORDER BY 'Number of Albums' DESC;
Resultaat:
+------------------------+--------------------+ | ArtistName | Number of Albums | |------------------------+--------------------| | Iron Maiden | 5 | | Michael Learns to Rock | 3 | | The Script | 3 | | Tom Jones | 3 | | Devin Townsend | 3 | | Allan Holdsworth | 2 | | Buddy Rich | 1 | | AC/DC | 1 | | Jim Reeves | 1 | +------------------------+--------------------+
Voorbeeld 6 – Met de HAVING-clausule
We kunnen het vorige voorbeeld aanpassen om alleen die artiesten op te nemen die meer dan een bepaald aantal albums hebben. We kunnen dit doen met de HAVING
clausule.
SELECT ArtistName, COUNT(al.AlbumId) 'Number of Albums' FROM Artists ar INNER JOIN Albums al ON al.ArtistId = ar.ArtistId GROUP BY ArtistName HAVING COUNT(al.AlbumId) > 2 ORDER BY 'Number of Albums' DESC;
Resultaat:
+------------------------+--------------------+ | ArtistName | Number of Albums | |------------------------+--------------------| | Iron Maiden | 5 | | Michael Learns to Rock | 3 | | The Script | 3 | | Tom Jones | 3 | | Devin Townsend | 3 | +------------------------+--------------------+
Voorbeeld 7 – Partitioneren met de OVER-clausule
U kunt de OVER
. gebruiken clausule met PARTITION BY
om de resultaten in partities te verdelen.
In dit voorbeeld gebruik ik OVER (PARTITION BY ArtistName)
om elk album weer te geven dat de artiest heeft geproduceerd, evenals het totale aantal albums voor die artiest.
SELECT ArtistName, AlbumName, COUNT(AlbumId) OVER (PARTITION BY ArtistName) 'Number of Albums from this Artist' FROM Artists ar INNER JOIN Albums al ON al.ArtistId = ar.ArtistId ORDER BY 'Number of Albums from this Artist' DESC;
Resultaat:
+------------------------+--------------------------+-------------------------------------+ | ArtistName | AlbumName | Number of Albums from this Artist | |------------------------+--------------------------+-------------------------------------| | Iron Maiden | Powerslave | 5 | | Iron Maiden | Somewhere in Time | 5 | | Iron Maiden | Piece of Mind | 5 | | Iron Maiden | Killers | 5 | | Iron Maiden | No Prayer for the Dying | 5 | | AC/DC | Powerage | 3 | | AC/DC | Back in Black | 3 | | AC/DC | Rock or Bust | 3 | | Michael Learns to Rock | Blue Night | 3 | | Michael Learns to Rock | Eternity | 3 | | Michael Learns to Rock | Scandinavia | 3 | | Devin Townsend | Ziltoid the Omniscient | 3 | | Devin Townsend | Casualties of Cool | 3 | | Devin Townsend | Epicloud | 3 | | Tom Jones | Long Lost Suitcase | 3 | | Tom Jones | Praise and Blame | 3 | | Tom Jones | Along Came Jones | 3 | | Allan Holdsworth | All Night Wrong | 2 | | Allan Holdsworth | The Sixteen Men of Tain | 2 | | Buddy Rich | Big Swing Face | 1 | | Jim Reeves | Singing Down the Lane | 1 | | The Script | No Sound Without Silence | 1 | +------------------------+--------------------------+-------------------------------------+
Houd er rekening mee dat hierdoor het aantal artiesten en albums wordt herhaald over meerdere rijen, maar dit is te verwachten wanneer we ook elk album op een eigen rij willen vermelden.
Voorbeeld 8 – Met STRING_AGG()
Als u niet wilt dat het aantal artiesten en albums wordt herhaald over meerdere rijen, zoals in het vorige voorbeeld, kunt u altijd de STRING_AGG()
gebruiken functie om de albums als een lijst uit te voeren. In dit geval heeft u de OVER
. niet nodig clausule.
Voorbeeld:
SELECT ArtistName, STRING_AGG(AlbumName, ', ') 'Albums', COUNT(AlbumId) 'Count' FROM Artists ar INNER JOIN Albums al ON al.ArtistId = ar.ArtistId GROUP BY ArtistName ORDER BY 'Count' DESC;
Resultaat:
+------------------------+--------------------------------------------------------------------------------+---------+ | ArtistName | Albums | Count | |------------------------+--------------------------------------------------------------------------------+---------| | Iron Maiden | Powerslave, Somewhere in Time, Piece of Mind, Killers, No Prayer for the Dying | 5 | | AC/DC | Powerage, Back in Black, Rock or Bust | 3 | | Michael Learns to Rock | Blue Night, Eternity, Scandinavia | 3 | | Devin Townsend | Ziltoid the Omniscient, Casualties of Cool, Epicloud | 3 | | Tom Jones | Long Lost Suitcase, Praise and Blame, Along Came Jones | 3 | | Allan Holdsworth | All Night Wrong, The Sixteen Men of Tain | 2 | | Buddy Rich | Big Swing Face | 1 | | Jim Reeves | Singing Down the Lane | 1 | | The Script | No Sound Without Silence | 1 | +------------------------+--------------------------------------------------------------------------------+---------+
VEEL rijen?
De COUNT()
functie retourneert het resultaat als een int data type. Als je zoveel rijen hebt dat het resultaat groter is dan wat int aankan, probeer COUNT_BIG()
in plaats daarvan.
COUNT_BIG()
werkt hetzelfde als COUNT()
, behalve dat de resultaten worden geretourneerd als een bigint gegevenstypewaarde.
U kunt ook overwegen om APPROX_COUNT_DISTINCT()
. te gebruiken in sommige gevallen.
APPROX_COUNT_DISTINCT()
geeft een geschatte waarde terug in plaats van een precieze waarde. Het is echter ontworpen om veel responsiever te zijn dan COUNT()
en COUNT_BIG()
, dus het kan handig zijn in tijden dat reactievermogen belangrijker is dan precisie.
Het is ontworpen om unieke, niet-null-waarden te retourneren, dus het zou alleen relevant zijn voor momenten waarop u normaal gesproken de DISTINCT
zou gebruiken clausule met COUNT_BIG()
.
Houd er ook rekening mee dat op het moment van schrijven APPROX_COUNT_DISTINCT()
bevindt zich in de openbare voorbeeldstatus.