Mon professeur m'a appris que `COUNT` ne compte pas les doublons

40

À l'université, mon professeur m'a appris cette année que cette déclaration SQL:

SELECT COUNT(length) FROM product

retournera 2avec le jeu de données suivant:

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

Elle a justifié cela en disant que COUNTcela ne compte pas les doublons.

J'ai dit à mon professeur que je pensais qu'elle avait commis une erreur. Elle m'a répondu que certains SGBD peuvent ou non compter des doublons.

Après avoir essayé beaucoup de SGBD, je n’en ai jamais trouvé qui ait ce comportement.

Ce SGBD existe-t-il?

Y a-t-il une raison pour qu'un professeur enseigne ce comportement? Et sans même mentionner que les autres SGBD peuvent se comporter différemment?


Pour votre information, le support du cours est disponible ici . La diapositive concernée se trouve dans le coin inférieur gauche à la page 10.

Jules Lamur
la source
1
Puisque les diapositives parlent de ANSi SQL, votre professeur a tort, même dans la norme de 1992 (voir contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt ), répertorie les divers comportements de décompte avec et sans DISTINCT. Vous voudrez peut-être visiter la bibliothèque avec une version mise à jour (qui inclut plus d'options comme ALL / OVER)
eckes

Réponses:

38

COUNT compte les doublons dans tous les SGBD dont je suis au courant, mais.

Y a-t-il une raison pour qu'un professeur enseigne ce comportement

Oui, il y a une raison. Dans la théorie relationnelle originale (qui sous-tend tous les SGBD relationnels modernes), la relation est un ensemble au sens mathématique de ce mot. Cela signifie qu'aucune relation ne peut contenir de doublons, y compris toutes les relations de transition, pas seulement vos «tables».

En suivant ce principe, vous pouvez dire qu’il SELECT length FROM productne contient déjà que deux lignes, donc les COUNTretours correspondants 2, pas 3.


Par exemple, dans le SGBD Rel , utilisez la relation indiquée dans la syntaxe question et tutorial D :

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

donne:

Résultat rel

Vadim Pushtaev
la source
1
Puisque nous avons eu des cours de théorie relationnelle avec ce professeur plus tard cette année, je pense que c'est la bonne réponse. Quoi qu'il en soit, je demanderai plus d'informations à mon professeur.
Jules Lamur
2
Le professeur parlait peut-être des SGBD en général, et pas seulement des SGBD SQL. Comme le montre l'édition, il existe des implémentations du modèle relationnel (par exemple, Rel), où le COUNTcomportement est différent de celui des implémentations SQL.
ypercubeᵀᴹ
47

Soit votre professeur a commis une erreur, soit vous avez mal compris ce qu'elle a dit. Dans le contexte de SGBD relationnels, tels qu'implémentés par différents fournisseurs, la fonction d'agrégat COUNT(<expression>)renvoie le nombre de valeurs non NULL de <expression>l'ensemble de résultats (ou d'un groupe).

Il existe un cas particulier de COUNT(*), qui renvoie le nombre de lignes dans le jeu de résultats ou le groupe, et non le nombre de valeurs. Ceci est équivalent à COUNT(<constant expression>), tel que COUNT(1).

De nombreuses bases de données supportent COUNT(DISTINCT <expression>), ce qui retournera le nombre de valeurs uniques de <expression>.

mustaccio
la source
13

Si votre professeur parle de SQL, la déclaration est fausse. COUNT(x)renverra le nombre de lignes où x, IS NOT NULLy compris les doublons. COUNT(*) or COUNT([constant])est un cas spécial qui comptera les lignes, même celles où chaque colonne est NULL. Toutefois, les doublons sont toujours comptés, sauf indication contraire de votre part COUNT(distinct x). Exemple:

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 *) est invalide autant que je sache.

En remarque, NULL introduit un comportement non intuitif. Par exemple:

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

c'est à dire:

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

S'il parle d'un système relationnel tel que décrit par exemple par le livre Databases, Types et le modèle relationnel: le troisième manifeste de CJ Date et Hugh Darwen, l'énoncé sera correct.

Disons que nous avons la relation:

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

Correspond à:

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

c'est à dire

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

qui retournerait 2 .

Lennart
la source
3

Voici comment cela fonctionne dans MS SQL Server

COUNT (*) renvoie le nombre d'éléments d'un groupe. Cela inclut les valeurs NULL et les doublons.

COUNT (ALL expression) évalue l'expression pour chaque ligne d'un groupe et renvoie le nombre de valeurs non NULL.

COUNT (expression DISTINCT) évalue l'expression pour chaque ligne d'un groupe et renvoie le nombre de valeurs uniques non nuls.

Daniel Björk
la source
1

Si la table avait ressemblé à ceci,

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

vous pouvez vous attendre à ce que la requête renvoie 2, au moins dans Oracle DB, car les valeurs NULL ne sont pas comptées. Les doublons sont toutefois très bien comptés.

Terje
la source
-7

peut-être veut-elle dire en conjonction avec unique, mais Count compte COUNT DUPLICATES. Il y a des professeurs qui ne connaissent pas leur métier, ne vous inquiétez pas, il vous suffit d'informer vos camarades de classe / amis pour qu'ils n'oublient pas de les renvoyer dans la vie réelle, encore mieux envoyer un message anonyme à votre professeur pour lui demander de ne pas le faire. comprendre certaines fonctions de SQL et vous voulez une démonstration, demandez à votre enseignant de trouver un moyen pour la classe de suggérer ce qu’il faut insérer, y compris les doublons (si les données ne sont pas volumineuses) et quand elle utilise le nombre de fonctions, vous l’avez. Certaines personnes y vont aussi. Quand elle dit d'autres bases de données, demandez à votre ami de lui demander lesquelles, puis doublez-la et dites-lui que vous avez essayé toutes ces bases de données et qu'elles ne fonctionnent pas comme elle le dit et que le nombre de doublons est pris en compte.

Dasda
la source
2
Je ne suis pas sûr de vouloir délibérément contrarier l'enseignant. Dans certains cas, il serait peut-être tout à fait approprié de les rencontrer personnellement et de poser des questions à ce sujet, votre contre-exemple étant prêt (juste pour montrer que vous avez une raison de demander). Néanmoins, les bases de l’approche sont valables; jusqu'à l'OP la direction spécifique à utiliser.
RDFozz