W SQL Server, COUNT()
funkcja zwraca liczbę elementów znalezionych w grupie. Możesz go użyć, aby dowiedzieć się, ile wierszy znajduje się w tabeli lub zestawie wyników.
Składnia
Składnia wygląda tak:
-- Aggregation Function Syntax COUNT ( { [ [ ALL | DISTINCT ] expression ] | * } ) -- Analytic Function Syntax COUNT ( [ ALL ] { expression | * } ) OVER ( [] )
ALL
stosuje funkcję agregującą do wszystkich wartości. To jest wartość domyślna.
DISTINCT
określa, że funkcja zwraca liczbę unikalnych wartości innych niż null.
expression
jest wyrażeniem dowolnego typu, z wyjątkiem obrazu , ntekst lub tekst . Funkcje agregujące i podzapytania nie są obsługiwane w wyrażeniu.
*
określa, że wszystkie wiersze powinny być zliczane i zwracane, w tym wiersze zduplikowane i wiersze zawierające wartości null. COUNT(*)
nie przyjmuje parametrów i nie obsługuje użycia DISTINCT
. Nie wymaga również wyrażenia parametr (ponieważ nie używa informacji o żadnej konkretnej kolumnie).
OVER ( [ <partition_by_clause> ]
dzieli zestaw wyników utworzony przez FROM
klauzuli na przegrody, do których funkcja jest stosowana. Jeśli nie zostanie określony, funkcja traktuje wszystkie wiersze zestawu wyników zapytania jako pojedynczą grupę.
Przykład 1 – Podstawowe użycie
Oto podstawowy przykład pokazujący, jak działa ta funkcja:
SELECT COUNT(*) AS 'Row Count' FROM Artists;
Wynik:
+-------------+ | Row Count | |-------------| | 16 | +-------------+
W tym przypadku w sekcji Wykonawcy znajduje się 16 wierszy tabela.
Dla pewności, oto one:
SELECT * FROM Artists;
Wynik:
+------------+------------------------+--------------+-------------+ | 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 | +------------+------------------------+--------------+-------------+
Zgodnie z oczekiwaniami zwracanych jest 16 wierszy.
Zauważ, że CountryId kolumna zawiera tylko wartości null. Będzie to przydatne w następnym przykładzie.
Przykład 2 – Określ kolumnę
W poprzednim przykładzie użyto gwiazdki (*
), aby określić wszystkie wiersze. Powoduje to zliczanie wszystkich wierszy, niezależnie od tego, czy występują duplikaty, czy też zawierają wartości null.
Możesz także określić konkretną kolumnę. Gdy to zrobisz, wartości null nie są liczone. Oznacza to, że wszystkie wiersze zawierające wartość null dla tej kolumny nie są liczone.
Oto przykład z użyciem CountryId kolumna jak wspomniano w poprzednim przykładzie:
SELECT COUNT(CountryId) AS 'Row Count' FROM Artists;
Wynik:
+-------------+ | Row Count | |-------------| | 0 | +-------------+
Jak widzieliśmy w poprzednim przykładzie, wszystkie wiersze dla tej kolumny mają wartość NULL
. Dlatego wynikowa liczba wierszy wynosi zero.
Dodajmy kilka wartości do tej kolumny:
UPDATE Artists SET CountryId = 2 WHERE ArtistName IN ( 'AC/DC', 'Karnivool', 'Birds of Tokyo', 'Bodyjar' );
Teraz ponownie policzmy wiersze dla tej kolumny:
SELECT COUNT(CountryId) AS 'Row Count' FROM Artists;
Wynik:
+-------------+ | Row Count | |-------------| | 4 | +-------------+
Przykład 3 – Z DISTINCT
W tym przykładzie użyto DISTINCT
klauzula zwracająca tylko różne wiersze (tj. niepowielone).
W poprzednim przykładzie zaktualizowałem tabelę tak, aby ten sam
CountryId
został zastosowany do czterech artystów (użyłem SET CountryId = 2
dla wszystkich czterech artystów). W rezultacie powstały cztery wiersze z tym samym
CountryId
.
Oto, co się stanie, jeśli policzę, ile różnych CountryId s są w tej tabeli:
SELECT COUNT(DISTINCT CountryId) 'Distinct CountryIds' FROM Artists;
Wynik:
+-----------------------+ | Distinct CountryIds | |-----------------------| | 1 | +-----------------------+
Należy się tego spodziewać, ponieważ chociaż istnieją cztery wiersze z CountryId , to wciąż tylko jeden odrębny CountryId .
Dla pewności uruchommy go razem z jego „nieodrębną” wersją:
SELECT COUNT(CountryId) 'Non Distinct', COUNT(DISTINCT CountryId) 'Distinct' FROM Artists;
Wynik:
+----------------+------------+ | Non Distinct | Distinct | |----------------+------------| | 4 | 1 | +----------------+------------+
Tak więc wersja nieodróżniająca pokazuje, ile razy
CountryId
pojawia się w tabeli, natomiast DISTINCT
wersja liczy wiele wystąpień jako 1.
Dodajmy kolejny CountryId do stołu:
UPDATE Artists SET CountryId = 1 WHERE ArtistName = 'Carabao';
A teraz uruchom zapytanie ponownie:
SELECT COUNT(CountryId) 'Non Distinct', COUNT(DISTINCT CountryId) 'Distinct' FROM Artists;
Wynik:
+----------------+------------+ | Non Distinct | Distinct | |----------------+------------| | 5 | 2 | +----------------+------------+
Przykład 4 – Użyj klauzuli WHERE
Oto krótki przykład użycia WHERE
klauzula.
SELECT COUNT(*) AS 'Row Count' FROM Artists WHERE ActiveFrom >= '2000-01-01';
Wynik:
+-------------+ | Row Count | |-------------| | 2 | +-------------+
Przykład 5 – Z GROUP BY
Oto przykład grupowania wykonawców w jednej kolumnie, a następnie zliczania wszystkich albumów każdego wykonawcy w drugiej kolumnie.
Przykład:
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;
Wynik:
+------------------------+--------------------+ | 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 | +------------------------+--------------------+
Przykład 6 – Z klauzulą HAVING
Możemy ulepszyć poprzedni przykład, aby uwzględnić tylko tych artystów, którzy mają więcej niż określoną liczbę albumów. Możemy to zrobić za pomocą HAVING
klauzula.
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;
Wynik:
+------------------------+--------------------+ | ArtistName | Number of Albums | |------------------------+--------------------| | Iron Maiden | 5 | | Michael Learns to Rock | 3 | | The Script | 3 | | Tom Jones | 3 | | Devin Townsend | 3 | +------------------------+--------------------+
Przykład 7 – Partycjonowanie z klauzulą OVER
Możesz użyć OVER
klauzula z PARTITION BY
podzielić wyniki na partycje.
W tym przykładzie używam OVER (PARTITION BY ArtistName)
aby wymienić każdy album, który artysta wyprodukował, a także łączną liczbę albumów tego artysty.
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;
Wynik:
+------------------------+--------------------------+-------------------------------------+ | 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 | +------------------------+--------------------------+-------------------------------------+
Zwróć uwagę, że powoduje to powtórzenie liczby wykonawców i albumów w wielu wierszach, ale należy się tego spodziewać, gdy chcemy również wyświetlić każdy album w osobnym wierszu.
Przykład 8 – z STRING_AGG()
Jeśli nie chcesz, aby każdy wykonawca i liczba albumów były powtarzane w wielu wierszach, jak w poprzednim przykładzie, zawsze możesz użyć STRING_AGG()
funkcja wyprowadzania albumów jako listy. W takim przypadku nie potrzebujesz OVER
klauzula.
Przykład:
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;
Wynik:
+------------------------+--------------------------------------------------------------------------------+---------+ | 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 | +------------------------+--------------------------------------------------------------------------------+---------+
DUŻO rzędów?
COUNT()
funkcja zwraca swój wynik jako int typ danych. Jeśli masz tak wiele wierszy, że wynik jest większy niż int może obsłużyć, spróbuj COUNT_BIG()
zamiast tego.
COUNT_BIG()
działa tak samo jak COUNT()
, z wyjątkiem tego, że jego wyniki są zwracane jako bigin wartość typu danych.
Możesz również rozważyć użycie APPROX_COUNT_DISTINCT()
w niektórych przypadkach.
APPROX_COUNT_DISTINCT()
zwraca wartość przybliżoną, a nie dokładną. Jest jednak zaprojektowany tak, aby był znacznie bardziej responsywny niż COUNT()
i COUNT_BIG()
, więc może się przydać w czasach, gdy szybkość reakcji jest ważniejsza niż precyzja.
Został zaprojektowany tak, aby zwracać unikalne wartości inne niż null, więc byłoby to istotne tylko w sytuacjach, w których normalnie używałbyś DISTINCT
klauzula z COUNT_BIG()
.
Pamiętaj też, że w momencie pisania APPROX_COUNT_DISTINCT()
jest w stanie publicznego podglądu.