Il mio professore mi ha insegnato che "COUNT" non conta i duplicati


40

All'università, il mio professore mi ha insegnato quest'anno che questa affermazione SQL:

SELECT COUNT(length) FROM product

tornerà 2con il seguente set di dati:

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

Lo ha giustificato dicendo che COUNTnon conta i duplicati.

Ho detto al mio professore che pensavo avesse commesso un errore. Mi ha risposto che alcuni DBMS possono o meno contare i duplicati.

Dopo aver provato molti DBMS, non ne ho mai trovato uno con questo comportamento.

Questo DBMS esiste?

C'è qualche motivo per un professore di insegnare questo comportamento? E senza nemmeno menzionare che altri DBMS potrebbero comportarsi diversamente?


Cordiali saluti, il supporto del corso è disponibile qui (in francese) . La diapositiva interessata si trova nell'angolo in basso a sinistra a pagina 10.


1
Poiché le diapositive parlano di ANSi SQL, il tuo professore ha torto, anche nello standard del 1992 (vedi pagina 125 qui contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt ) elenca i vari comportamenti da tenere in considerazione con e senza DISTINCT. Potresti voler visitare la biblioteca in una versione aggiornata (che include più opzioni come ALL / OVER)
verifica il

Risposte:


38

COUNT conta i duplicati in tutti i DBMS di cui sono a conoscenza, ma.

C'è qualche motivo per un professore di insegnare questo comportamento

Sì, c'è un motivo. Nella teoria relazionale originale (che sta alla base di tutti i moderni DBMS relazionali ) la relazione è un insieme in senso matematico di questa parola. Ciò significa che nessuna relazione può contenere affatto duplicati, comprese tutte le relazioni di transizione, non solo le vostre "tabelle".

Seguendo questo principio si può dire che SELECT length FROM productcontiene già solo due righe, quindi i COUNTritorni corrispondenti 2, no 3.


Ad esempio, in Rel DBMS, usando la relazione fornita nella domanda e nella sintassi del tutorial D :

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

dà:

Risultato relativo


1
Dato che abbiamo tenuto corsi di teoria relazionale con questo professore entro la fine dell'anno, penso che questa sia la risposta corretta. Ad ogni modo, chiederò al mio professore ulteriori informazioni.
Jules Lamur,

2
L'insegnante forse stava parlando di DBMS in generale, non solo di DBMS SQL. Come mostra la modifica, ci sono implementazioni del modello relazionale (ad esempio Rel), dove COUNTsi comporta diversamente dalle implementazioni SQL.
ypercubeᵀᴹ

47

O il tuo professore ha fatto un errore o hai frainteso quello che ha detto. Nel contesto dei DBMS relazionali, come implementato da vari fornitori, la funzione aggregata COUNT(<expression>)restituisce il numero di valori non NULL <expression>nel set di risultati (o in un gruppo).

C'è un caso speciale di COUNT(*), che restituisce il numero di righe nel set di risultati o nel gruppo, non il numero di valori di qualsiasi cosa. Questo è equivalente a COUNT(<constant expression>), ad esempio COUNT(1).

Molti database supportano COUNT(DISTINCT <expression>), che si restituisce il numero di valori unici di <expression>.


13

Se il tuo professore parla di SQL, l'affermazione è sbagliata. COUNT(x)restituirà il numero di righe in cui x IS NOT NULLinclusi i duplicati. COUNT(*) or COUNT([constant])è un caso speciale che conterà le righe, anche quelle in cui si trova ogni colonna NULL. Tuttavia, i duplicati vengono sempre conteggiati, a meno che non venga specificato COUNT(distinct x). Esempio:

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 *) AFAIK non è valido.

Come nota a margine, NULL introduce alcuni comportamenti non intuitivi. Come esempio:

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

vale a dire:

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

Se sta parlando di un sistema relazionale come descritto, ad esempio, dal libro Database, Tipi e Modello relazionale: The Third Manifesto di CJ Date e Hugh Darwen - sarebbe un'affermazione corretta.

Dì che abbiamo la relazione:

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

corrisponde a:

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

vale a dire

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

che restituirebbe 2 .


3

Funziona così in MS SQL Server

COUNT (*) restituisce il numero di elementi in un gruppo. Ciò include valori NULL e duplicati.

COUNT (TUTTA espressione) valuta l'espressione per ogni riga in un gruppo e restituisce il numero di valori non null.

COUNT (espressione DISTINCT) valuta l'espressione per ogni riga di un gruppo e restituisce il numero di valori univoci e non nulli.


1

Se il tavolo fosse stato così,

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

potresti aspettarti che la query restituisca 2, almeno in Oracle DB, poiché i null non vengono conteggiati. I duplicati vengono comunque conteggiati bene.


-7

forse intende in congiunzione con unico, ma Count conta DUPLICATES. Ci sono alcuni insegnanti che non conoscono le loro cose, nessuna preoccupazione informa i tuoi compagni di classe / amici in modo che quando passano al livello superiore e alla vita reale non dimenticheranno, è meglio inviare un messaggio anonimo al tuo insegnante chiedendole di non averlo fatto comprendere alcune delle funzioni sql e desiderare una dimostrazione, fare in modo che l'insegnante abbia un modo per la classe di suggerire cosa inserire i duplicati (non avere i dati di grandi dimensioni) e quando usa il conteggio delle funzioni, la ottieni. Alcune persone lo raccoglieranno, anche quando dice altri database, chiedi al tuo amico di chiederle quali, quindi raddoppiarla e dire che hai provato tutti quei database e non funzionano come ha detto e che conta raccoglie duplicati.


2
Non sono sicuro di voler deliberatamente antagonizzare l'insegnante. Con alcuni, potrebbe essere del tutto adeguato incontrarli personalmente e chiederli, con il tuo contro-esempio pronto (solo per dimostrare che hai un motivo per chiedere). Tuttavia, le basi dell'approccio sono valide; fino all'OP la direzione specifica da utilizzare.
RDFozz
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.