Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Come funziona COUNT() in SQL Server

In SQL Server, il COUNT() la funzione restituisce il numero di elementi trovati in un gruppo. Puoi usarlo per scoprire quante righe ci sono in una tabella o in un set di risultati.

Sintassi

La sintassi è questa:

-- Aggregation Function Syntax  
COUNT ( { [ [ ALL | DISTINCT ] expression ] | * } )  

-- Analytic Function Syntax  
COUNT ( [ ALL ]  { expression | * } ) OVER ( [  ] )

ALL applica la funzione di aggregazione a tutti i valori. Questo è il valore predefinito.

DISTINCT specifica che la funzione restituisce il numero di valori non nulli univoci.

expression è un'espressione di qualsiasi tipo, eccetto immagine , ntesto o testo . Le funzioni aggregate e le sottoquery non sono supportate nell'espressione.

* specifica che tutte le righe devono essere contate e restituite, comprese le righe duplicate e le righe che contengono valori Null. COUNT(*) non accetta parametri e non supporta l'uso di DISTINCT . Inoltre non richiede un'espressione parametro (perché non utilizza informazioni su una colonna in particolare).

OVER ( [ <partition_by_clause> ] divide il set di risultati prodotto dal FROM clausola in partizioni a cui viene applicata la funzione. Se non specificata, la funzione tratta tutte le righe del set di risultati della query come un unico gruppo.

Esempio 1 – Utilizzo di base

Ecco un esempio di base che mostra come funziona questa funzione:

SELECT COUNT(*) AS 'Row Count'
FROM Artists;

Risultato:

+-------------+
| Row Count   |
|-------------|
| 16          |
+-------------+

In questo caso ci sono 16 righe in Artisti tabella.

Per sicurezza, eccoli qui:

SELECT *
FROM Artists;

Risultato:

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

Come previsto, vengono restituite 16 righe.

Si noti che CountryId la colonna non contiene altro che valori nulli. Questo sarà utile per il prossimo esempio.

Esempio 2:specifica una colonna

L'esempio precedente utilizzava un asterisco (* ) per specificare tutte le righe. Ciò comporta il conteggio di tutte le righe, indipendentemente dal fatto che siano presenti duplicati o che contengano valori null.

Puoi anche specificare una colonna particolare. Quando lo fai, i valori nulli non vengono conteggiati. Ovvero, tutte le righe contenenti un valore nullo per quella colonna non vengono conteggiate.

Ecco un esempio che utilizza CountryId colonna come indicato nell'esempio precedente:

SELECT COUNT(CountryId) AS 'Row Count'
FROM Artists;

Risultato:

+-------------+
| Row Count   |
|-------------|
| 0           |
+-------------+

Come abbiamo visto nell'esempio precedente, tutte le righe per questa colonna sono NULL . Pertanto, il conteggio delle righe risultante è zero.

Aggiungiamo alcuni valori in quella colonna:

UPDATE Artists
SET CountryId = 2
WHERE ArtistName IN (
    'AC/DC', 
    'Karnivool', 
    'Birds of Tokyo', 
    'Bodyjar'
    );

Ora contiamo di nuovo le righe per quella colonna:

SELECT COUNT(CountryId) AS 'Row Count'
FROM Artists;

Risultato:

+-------------+
| Row Count   |
|-------------|
| 4           |
+-------------+

Esempio 3 – Con DISTINCT

Questo esempio usa il DISTINCT clausola per restituire solo righe distinte (cioè non duplicate).

Nell'esempio precedente, ho aggiornato la tabella in modo che lo stesso CountryId è stato applicato a quattro artisti (ho usato SET CountryId = 2 per tutti e quattro gli artisti). Ciò ha prodotto quattro righe con lo stesso CountryId .

Ecco cosa succede se conto quanti CountryId distinti s sono in quella tabella:

SELECT COUNT(DISTINCT CountryId) 'Distinct CountryIds'
FROM Artists;

Risultato:

+-----------------------+
| Distinct CountryIds   |
|-----------------------|
| 1                     |
+-----------------------+

Questo è prevedibile, perché, sebbene ci siano quattro righe con un CountryId , è ancora solo un CountryId distinto .

Per sicurezza, eseguiamolo insieme alla sua versione "non distinta":

SELECT 
  COUNT(CountryId) 'Non Distinct',
  COUNT(DISTINCT CountryId) 'Distinct'
FROM Artists;

Risultato:

+----------------+------------+
| Non Distinct   | Distinct   |
|----------------+------------|
| 4              | 1          |
+----------------+------------+

Quindi la versione non distinta mostra quante volte CountryId appare nella tabella, mentre il DISTINCT la versione conta più occorrenze come 1.

Aggiungiamo un altro CountryId al tavolo:

UPDATE Artists
SET CountryId = 1
WHERE ArtistName = 'Carabao';

E ora esegui di nuovo la query:

SELECT 
  COUNT(CountryId) 'Non Distinct',
  COUNT(DISTINCT CountryId) 'Distinct'
FROM Artists;

Risultato:

+----------------+------------+
| Non Distinct   | Distinct   |
|----------------+------------|
| 5              | 2          |
+----------------+------------+

Esempio 4:utilizzare una clausola WHERE

Ecco un rapido esempio usando un WHERE clausola.

SELECT COUNT(*) AS 'Row Count'
FROM Artists
WHERE ActiveFrom >= '2000-01-01';

Risultato:

+-------------+
| Row Count   |
|-------------|
| 2           |
+-------------+

Esempio 5 – Con GROUP BY

Ecco un esempio di raggruppamento degli artisti in una colonna, quindi conteggio di tutti gli album per ciascun artista nell'altra colonna.

Esempio:

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;

Risultato:

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

Esempio 6 – Con la clausola HAVING

Possiamo modificare l'esempio precedente per includere solo quegli artisti che hanno più di un certo numero di album. Possiamo farlo usando il HAVING clausola.

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;

Risultato:

+------------------------+--------------------+
| ArtistName             | Number of Albums   |
|------------------------+--------------------|
| Iron Maiden            | 5                  |
| Michael Learns to Rock | 3                  |
| The Script             | 3                  |
| Tom Jones              | 3                  |
| Devin Townsend         | 3                  |
+------------------------+--------------------+

Esempio 7 – Partizionamento con la clausola OVER

Puoi usare il OVER clausola con PARTITION BY per dividere i risultati in partizioni.

In questo esempio, utilizzo OVER (PARTITION BY ArtistName) per elencare ogni album che l'artista ha prodotto, così come il numero totale di album per quell'artista.

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;

Risultato:

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

Tieni presente che questo fa sì che il conteggio dell'artista e dell'album venga ripetuto su più righe, ma questo è prevedibile quando vogliamo anche elencare ogni album su una riga separata.

Esempio 8 – Con STRING_AGG()

Se non vuoi che il conteggio di ogni artista e album venga ripetuto su più righe come nell'esempio precedente, puoi sempre utilizzare il STRING_AGG() funzione per emettere gli album come un elenco. In questo caso, non avresti bisogno del OVER clausola.

Esempio:

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;

Risultato:

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

TANTE righe?

Il COUNT() la funzione restituisce il risultato come int tipo di dati. Se hai così tante righe che il risultato è più grande di quello che int può gestire, prova COUNT_BIG() invece.

COUNT_BIG() funziona come COUNT() , tranne per il fatto che i suoi risultati vengono restituiti come bigint valore del tipo di dati.

Potresti anche prendere in considerazione l'utilizzo di APPROX_COUNT_DISTINCT() in alcuni casi.

APPROX_COUNT_DISTINCT() restituisce un valore approssimativo, anziché un valore preciso. Tuttavia, è progettato per essere molto più reattivo di COUNT() e COUNT_BIG() , quindi potrebbe essere utile nei momenti in cui la reattività è più importante della precisione.

È progettato per restituire valori univoci e non nulli, quindi sarebbe rilevante solo per i momenti in cui normalmente utilizzeresti il ​​DISTINCT clausola con COUNT_BIG() .

Tieni inoltre presente che, al momento della scrittura di APPROX_COUNT_DISTINCT() è in stato di anteprima pubblica.