Mi profesor me enseñó que `COUNT` no cuenta duplicados

40

En la universidad, mi profesor me enseñó este año que esta declaración SQL:

SELECT COUNT(length) FROM product

regresará 2con el siguiente conjunto de datos:

|   product         |
|id | length | code |
|-------------------|
| 1 |    11  | X00  |
| 2 |    11  | C02  |
| 3 |    40  | A31  |

Ella lo justificó diciendo que COUNTno cuenta duplicados.

Le dije a mi profesor que pensaba que había cometido un error. Ella me respondió que algunos DBMS pueden o no contar duplicados.

Después de probar muchos DBMS, nunca he encontrado uno que tenga este comportamiento.

¿Existe este DBMS?

¿Hay alguna razón para que un profesor enseñe este comportamiento? ¿Y sin siquiera mencionar que otros DBMS pueden comportarse de manera diferente?


Para su información, el soporte del curso está disponible aquí (en francés) . La diapositiva en cuestión se encuentra en la esquina inferior izquierda en la página 10.

Jules Lamur
fuente
1
Como las diapositivas hablan de ANSi SQL, su profesor está equivocado, incluso en el estándar de 1992 (consulte la página 125 aquí contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt ) enumera los diversos comportamientos para contar con y sin DISTINCT. Es posible que desee visitar la biblioteca con una versión actualizada (que incluye más opciones como ALL / OVER)
eckes

Respuestas:

38

COUNT cuenta duplicados en todos los DBMS que conozco, pero.

¿Hay alguna razón para que un profesor enseñe este comportamiento?

Sí, hay una razón En la teoría relacional original (que subyace a todos los DBMS relacionales modernos) la relación es un conjunto en sentido matemático de esta palabra. Eso significa que ninguna relación puede contener duplicados, incluidas todas las relaciones de transición, no solo sus "tablas".

Siguiendo este principio, puede decir que SELECT length FROM productya contiene solo dos filas, por lo tanto , los COUNTretornos correspondientes 2no 3.


Por ejemplo, en Rel DBMS, usando la relación dada en la pregunta y la sintaxis del Tutorial D :

SUMMARIZE product {length} BY {}: {c := COUNT()}

da:

Resultado rel

Vadim Pushtaev
fuente
1
Como tuvimos cursos de teoría de la relación con este profesor más adelante este año, creo que esta es la respuesta correcta. De todos modos, le pediré más información a mi profesor.
Jules Lamur
2
El profesor tal vez estaba hablando de DBMS en general, no solo de DBMS de SQL. Como muestra la edición, hay implementaciones del modelo relacional (por ejemplo, Rel), donde se COUNTcomporta de manera diferente a las implementaciones de SQL.
ypercubeᵀᴹ
47

O tu profesor cometió un error o entendiste mal lo que dijo. En el contexto de los DBMS relacionales, implementados por varios proveedores, la función agregada COUNT(<expression>)devuelve el número de valores no NULL del <expression>conjunto de resultados (o un grupo).

Hay un caso especial de COUNT(*), que devuelve el número de filas en el conjunto de resultados o grupo, no el número de valores de nada. Esto es equivalente a COUNT(<constant expression>), como COUNT(1).

Muchas bases de datos son compatibles COUNT(DISTINCT <expression>), lo que devolverá el número de valores únicos de <expression>.

mustaccio
fuente
13

Si su profesor está hablando de SQL, la afirmación es incorrecta. COUNT(x)devolverá el número de filas donde x IS NOT NULLincluyendo duplicados. COUNT(*) or COUNT([constant])es un caso especial que contará las filas, incluso aquellas donde está cada columna NULL. Sin embargo, los duplicados siempre se cuentan, a menos que usted especifique COUNT(distinct x). Ejemplo:

with t(x,y) as ( values (null,null),(null,1),(1,null),(1,1) )

select count(*) from t
4

select count(1) from t
4

select count(distinct 1) from t
1

select count(x) from t
2

select count(distinct x) from t
1

COUNT(distinct *) es inválido AFAIK.

Como nota al margen, NULL introduce un comportamiento poco intuitivo. Como ejemplo:

SELECT SUM(x) + SUM(y),  SUM(x + y) FROM T
4, 2

es decir:

SUM(x)+SUM(y) <> SUM(x+y)

Si él / ella está hablando de un sistema relacional como se describe, por ejemplo, en el libro Bases de datos, tipos y modelo relacional: El tercer manifiesto de CJ Date y Hugh Darwen, sería una afirmación correcta.

Digamos que tenemos la relación:

STUDENTS = Relation(["StudentId", "Name"]
                    , [{"StudentId":'S1', "Name":'Anne'},
                       {"StudentId":'S2', "Name":'Anne'},
                       {"StudentId":'S3', "Name":'Cindy'},
                     ])
SELECT COUNT(NAME) FROM STUDENTS

corresponde a:

COUNT(STUDENTS.project(['Name']))

es decir

COUNT( Relation(["Name"]
               , [{"Name":'Anne'},
                  {"Name":'Cindy'},
                ]) )

que devolvería 2 .

Lennart
fuente
3

Así es como funciona en MS SQL Server

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

COUNT (TODAS las expresiones) evalúa las expresiones para cada fila de un grupo y devuelve el número de valores no nulos.

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

Daniel Björk
fuente
1

Si la mesa se hubiera visto así,

|   product         |
|id | length | code |
|-------------------|
| 1 |    11  | X00  |
| 2 |    11  | C02  |
| 3 |  null  | A31  |

puede esperar que la consulta devuelva 2, al menos en Oracle DB, ya que no se cuentan los valores nulos. Sin embargo, los duplicados se cuentan muy bien.

Terje
fuente
-7

tal vez ella quiere decir en conjunto con único, pero Count cuenta DUPLICADOS. Hay algunos maestros que no conocen sus cosas, no se preocupe, solo informe a sus compañeros de clase / amigos para que cuando pasen a un nivel superior de db y la vida real no lo olviden, mejor aún, envíe un mensaje anónimo a su maestro pidiéndole que no entiende algunas de las funciones sql y quiere una demostración, haga que su maestra encuentre una forma para que la clase sugiera qué insertar incluyen duplicados (no los datos sean grandes) y cuando usa el recuento de funciones, la tiene. Algunas personas se darán cuenta, también cuando dice otras bases de datos, haga que su amiga le pregunte cuáles, luego la atrape dos veces y diga que probó todas esas bases de datos y que no funcionan como ella dijo y que el conteo recoge duplicados.

dasda
fuente
2
No estoy seguro de que me propusiera antagonizar deliberadamente con el maestro. Con algunos, puede ser completamente adecuado reunirse con ellos personalmente y preguntarles al respecto, con su contraejemplo listo (solo para demostrar que tiene una razón para preguntar). Aún así, los conceptos básicos del enfoque son válidos; hasta el OP la dirección específica para usar.
RDFozz