sql >> Base de Datos >  >> RDS >> Sqlserver

Cómo funciona COUNT() en SQL Server

En SQL Server, COUNT() La función devuelve el número de elementos encontrados en un grupo. Puede usarlo para averiguar cuántas filas hay en una tabla o conjunto de resultados.

Sintaxis

La sintaxis es así:

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

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

ALL aplica la función agregada a todos los valores. Este es el valor predeterminado.

DISTINCT especifica que la función devuelve el número de valores no nulos únicos.

expression es una expresión de cualquier tipo, excepto imagen , ntext o texto . Las funciones agregadas y las subconsultas no se admiten en la expresión.

* especifica que se deben contar y devolver todas las filas, incluidas las filas duplicadas y las filas que contienen valores nulos. COUNT(*) no toma parámetros y no admite el uso de DISTINCT . Tampoco requiere una expresión parámetro (porque no usa información sobre ninguna columna en particular).

OVER ( [ <partition_by_clause> ] divide el conjunto de resultados producido por FROM cláusula en particiones a las que se aplica la función. Si no se especifica, la función trata todas las filas del conjunto de resultados de la consulta como un solo grupo.

Ejemplo 1:uso básico

Aquí hay un ejemplo básico que muestra cómo funciona esta función:

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

Resultado:

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

En este caso hay 16 filas en Artistas mesa.

Solo para estar seguro, aquí están:

SELECT *
FROM Artists;

Resultado:

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

Como se esperaba, se devuelven 16 filas.

Observe que CountryId columna no contiene nada más que valores nulos. Esto será útil para el siguiente ejemplo.

Ejemplo 2:especificar una columna

El ejemplo anterior usó un asterisco (* ) para especificar todas las filas. Esto da como resultado que se cuenten todas las filas, independientemente de si hay duplicados o si alguno contiene valores nulos.

También puede especificar una columna en particular. Cuando hace esto, los valores nulos no se cuentan. Es decir, no se cuenta ninguna fila que contenga un valor nulo para esa columna.

Aquí hay un ejemplo usando el CountryId columna como se menciona en el ejemplo anterior:

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

Resultado:

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

Como vimos en el ejemplo anterior, todas las filas de esta columna son NULL . Por lo tanto, el recuento de filas resultante es cero.

Agreguemos algunos valores en esa columna:

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

Ahora volvamos a contar las filas de esa columna:

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

Resultado:

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

Ejemplo 3:con DISTINTO

Este ejemplo usa el DISTINCT cláusula para devolver solo filas distintas (es decir, no duplicadas).

En el ejemplo anterior, actualicé la tabla para que el mismo CountryId se aplicó a cuatro artistas (utilicé SET CountryId = 2 para los cuatro artistas). Esto resultó en cuatro filas con el mismo CountryId .

Esto es lo que sucede si cuento cuántos CountryId distintos s están en esa tabla:

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

Resultado:

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

Esto es de esperar porque, aunque hay cuatro filas con un CountryId , sigue siendo solo un CountryId distinto .

Solo para estar seguros, ejecútelo junto con su versión "no distinta":

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

Resultado:

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

Entonces, la versión no distinta muestra cuántas veces CountryId aparece en la tabla, mientras que DISTINCT versión cuenta múltiples ocurrencias como 1.

Agreguemos otro CountryId a la mesa:

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

Y ahora ejecuta la consulta de nuevo:

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

Resultado:

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

Ejemplo 4:utilice una cláusula WHERE

Aquí hay un ejemplo rápido usando un WHERE cláusula.

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

Resultado:

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

Ejemplo 5:con GROUP BY

Este es un ejemplo de cómo agrupar a los artistas en una columna y luego contar todos los álbumes de cada artista en la otra columna.

Ejemplo:

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;

Resultado:

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

Ejemplo 6:con la cláusula HAVING

Podemos modificar el ejemplo anterior para incluir solo a aquellos artistas que tienen más de un cierto número de álbumes. Podemos hacer esto usando HAVING cláusula.

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;

Resultado:

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

Ejemplo 7:partición con la cláusula OVER

Puedes usar el OVER cláusula con PARTITION BY para dividir los resultados en particiones.

En este ejemplo, uso OVER (PARTITION BY ArtistName) para enumerar cada álbum que ha producido el artista, así como el número total de álbumes de ese 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;

Resultado:

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

Tenga en cuenta que esto hace que el recuento de artistas y álbumes se repita en varias filas, pero esto es de esperar cuando también queremos enumerar cada álbum en su propia fila.

Ejemplo 8:con STRING_AGG()

Si no desea que el recuento de cada artista y álbum se repita en varias filas como en el ejemplo anterior, siempre puede usar STRING_AGG() función para generar los álbumes como una lista. En este caso, no necesitarías OVER cláusula.

Ejemplo:

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;

Resultado:

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

¿MUCHAS filas?

El COUNT() la función devuelve su resultado como un int tipo de datos. Si tiene tantas filas que el resultado es más grande que int puede manejar, intente COUNT_BIG() en su lugar.

COUNT_BIG() funciona igual que COUNT() , excepto que sus resultados se devuelven como bigint valor del tipo de datos.

También podría considerar usar APPROX_COUNT_DISTINCT() en algunos casos.

APPROX_COUNT_DISTINCT() devuelve un valor aproximado, en lugar de un valor preciso. Sin embargo, está diseñado para responder mucho mejor que COUNT() y COUNT_BIG() , por lo que podría ser útil en momentos en que la capacidad de respuesta es más importante que la precisión.

Está diseñado para devolver valores únicos, no nulos, por lo que solo sería relevante para los momentos en los que normalmente usaría DISTINCT cláusula con COUNT_BIG() .

También tenga en cuenta que, al momento de escribir APPROX_COUNT_DISTINCT() está en estado de versión preliminar pública.