En SQL, ¿cuál es la diferencia entre count (columna) y count (*)?

205

Tengo la siguiente consulta:

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

¿Cuál sería la diferencia si reemplazara todas las llamadas count(column_name)a count(*)?

Esta pregunta se inspiró en ¿Cómo encuentro valores duplicados en una tabla en Oracle? .


Para aclarar la respuesta aceptada (y tal vez mi pregunta), reemplazar count(column_name)con count(*)devolvería una fila adicional en el resultado que contiene nullay el recuento de nullvalores en la columna.

Bill el lagarto
fuente

Respuestas:

235

count(*)cuenta NULL y count(column)no

[edit] agregó este código para que la gente pueda ejecutarlo

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

resultados 7 3 2

SQLMenace
fuente
8
Simplemente curioso: si tiene una fila con todos los NULL, ¿lo contaría (*) todavía lo contaría, o es solo contar (columna) para todas las columnas?
Joel Coehoorn
77
¿Es este estándar en todos los DBMS?
Eclipse el
51
Vale la pena mencionar que si tiene una columna no anulable como ID, entonces count (ID) mejorará significativamente el rendimiento sobre count (*).
tsilb
12
@tsilb: La respuesta publicada por @Alan establece que "el recuento (*) se calcula mirando los índices de la tabla en cuestión en lugar de las filas de datos reales" que, de ser cierto, invalidan su comentario. Aprecio que @Alan pueda estar equivocado, pero estoy interesado en la fuente de su información para averiguar cuál es la correcta.
Tony
12
@tsilb: Muchos optimizadores de consultas modernos optimizarán el recuento (*) para usar índices cuando tenga sentido.
Shannon Severance
37

Otra diferencia menor, entre usar * y una columna específica, es que en el caso de la columna puede agregar la palabra clave DISTINCT y restringir el conteo a valores distintos:

select column_a, count(distinct column_b)
from table
group by column_a
having count(distinct column_b) > 1;
Brannon
fuente
1
¿Debería ser diferente el grupo por columna y el que se está contando? de lo contrario no obtendría nada de esta consulta
steevc
Sí, lo siento ... No me había dado cuenta de que eran la misma columna en el ejemplo. Actualizaré la publicación.
Brannon
16

Una diferencia adicional y quizás sutil es que en algunas implementaciones de bases de datos el recuento (*) se calcula mirando los índices en la tabla en cuestión en lugar de las filas de datos reales. Como no se especifica una columna específica, no hay necesidad de molestarse con las filas reales y sus valores (como lo sería si contara una columna específica). Permitir que la base de datos use los datos del índice puede ser significativamente más rápido que hacer que cuente filas "reales".

Alan
fuente
55
+1 Sí, ciertamente cierto para Oracle, y para PostgreSQL desde 9.2 en adelante.
David Aldridge
@DavidAldridge ¿Puede proporcionar un puntero a la documentación (especialmente para postgresql) donde se menciona esto? Gracias.
Bhushan
@Bhushan aquí tienes wiki.postgresql.org/wiki/Index-only_scans
David Aldridge
10

La explicación en los documentos ayuda a explicar esto:

COUNT (*) devuelve el número de elementos en un grupo, incluidos valores NULL y duplicados.

COUNT (expresión) evalúa la expresión para cada fila de un grupo y devuelve el número de valores no nulos.

Entonces count (*) incluye valores nulos, el otro método no.

Peter C
fuente
Para SQL newbs: ¿A qué archivo de ayuda se refiere?
Bill the Lizard
10

Podemos usar el Explorador de datos de Stack Exchange para ilustrar la diferencia con una consulta simple. La tabla Usuarios en la base de datos de Stack Overflow tiene columnas que a menudo se dejan en blanco, como la URL del sitio web del usuario.

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

Si ejecuta la consulta anterior en el Explorador de datos , verá que el recuento es el mismo para count(Id)y count(*)porque la Idcolumna no permite nullvalores. Sin WebsiteUrlembargo, el recuento es mucho más bajo porque esa columna lo permite null.

Bill el lagarto
fuente
2

Básicamente, la COUNT(*)función devuelve todas las filas de una tabla, mientras COUNT(COLUMN_NAME)que no; es decir, excluye valores nulos que todos aquí también han respondido aquí. Pero la parte más interesante es que las consultas y la base de datos optimizada es mejor usar a COUNT(*)menos que haga múltiples conteos o una consulta compleja en lugar de hacerlo COUNT(COLUMN_NAME). De lo contrario, realmente reducirá el rendimiento de su base de datos al tratar con una gran cantidad de datos.

Ahmedul Kabir
fuente
1
  • La oración COUNT (*) indica que SQL Server devuelve todas las filas de una tabla, incluidos NULL.
  • COUNT (column_name) solo recupera las filas que tienen un valor no nulo en las filas.

Consulte el siguiente código para las ejecuciones de prueba de SQL Server 2008:

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

COUNT(*) - Devuelve el número total de registros en una tabla (incluidos los registros con valores NULL).

COUNT(Column Name) - Devuelve el número total de registros no NULL. Significa que, ignora contar registros con valores NULL en esa columna en particular.

Arun Solomon
fuente
0

Es mejor usar

Count(1) in place of column name or * 

para contar el número de filas en una tabla, es más rápido que cualquier formato porque nunca va a verificar si el nombre de la columna en la tabla existe o no

Ali Adravi
fuente
44
Incorrecto para Oracle al menos, y para otros RDBMS también sospecho. Internamente count (1) se transforma en count (*). En particular, el rendimiento del recuento (*) no se ve afectado negativamente por el tamaño de las filas, que es un error común.
David Aldridge
Esto es cierto para SQL Server. Como dijo @Ali Adravi, COUNT(*)en comparación con COUNT(columnName)no irá a verificar el valor de la columna, porque solo enumera las filas. ¡Pero COUNT(columnName)es más lento incluso el countaplicado en una idcolumna! Al menos en SQL Server, por supuesto.
ABS
0

No hay diferencia si una columna está arreglada en su tabla, si desea usar más de una columna de lo que tiene que especificar cuántas columnas necesita contar ...

Gracias,

Hiren gardhariya
fuente
0

Como se mencionó en las respuestas anteriores, Count(*)cuenta incluso las NULLcolumnas, mientras que count(Columnname)cuenta solo si la columna tiene valores.

Siempre es mejor práctica para evitar *( Select *, count *, ...)

Unna
fuente
No es en absoluto una mejor práctica para evitarCOUNT(*)
David Faber