Profesor saya mengajari saya bahwa `COUNT` tidak menghitung duplikat


40

Di universitas, profesor saya mengajari saya tahun ini bahwa pernyataan SQL ini:

SELECT COUNT(length) FROM product

akan kembali 2dengan dataset berikut:

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

Dia membenarkannya dengan mengatakan itu COUNTtidak termasuk duplikat.

Saya memberi tahu profesor saya bahwa saya pikir dia membuat kesalahan. Dia menjawab saya bahwa beberapa DBMS mungkin menghitung duplikat atau tidak.

Setelah mencoba banyak DBMS, saya tidak pernah menemukan yang memiliki perilaku ini.

Apakah DBMS ini ada?

Apakah ada alasan bagi seorang profesor untuk mengajarkan perilaku ini? Dan bahkan tanpa menyebutkan bahwa DBMS lain mungkin berperilaku berbeda?


FYI, dukungan kursus tersedia di sini (dalam bahasa Prancis) . Slide yang bersangkutan ada di sudut kiri bawah pada halaman 10.


1
Karena slide tersebut berbicara tentang ANSi SQL, profesor Anda salah, bahkan dalam standar 1992 (lihat halaman 125 di sini contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt ) mencantumkan berbagai perilaku untuk menghitung dengan dan tanpa DISTINCT. Anda mungkin ingin mengunjungi perpustakaan menggunakan versi yang diperbarui (yang mencakup lebih banyak opsi seperti ALL / OVER)
eckes

Jawaban:


38

COUNT menghitung duplikat di semua DBMS yang saya ketahui, tetapi.

Apakah ada alasan bagi seorang profesor untuk mengajarkan perilaku ini

Ya, ada alasannya. Dalam teori relasional asli (yang mendasari semua DBMSes relasional modern) hubungan adalah himpunan dalam arti matematika dari kata ini. Itu berarti bahwa tidak ada hubungan yang bisa mengandung duplikat sama sekali, termasuk semua hubungan transisi, bukan hanya "tabel" Anda.

Mengikuti prinsip ini, Anda dapat mengatakan bahwa SELECT length FROM productsudah berisi hanya dua baris, karenanya COUNTpengembalian yang sesuai 2, tidak 3.


Misalnya, dalam Rel DBMS, menggunakan relasi yang diberikan dalam pertanyaan dan sintaks D Tutorial :

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

memberi:

Hasil rel


1
Karena kami memiliki kursus teori relasional dengan profesor ini akhir tahun ini, saya pikir ini adalah jawaban yang benar. Ngomong-ngomong, saya akan menanyakan informasi lebih lanjut kepada profesor saya.
Jules Lamur

2
Guru mungkin berbicara tentang DBMS secara umum, tidak hanya tentang SQL DBMS. Seperti yang ditunjukkan oleh hasil edit, ada implementasi model relasional (misalnya Rel), di mana COUNTberperilaku berbeda dari implementasi SQL.
ypercubeᵀᴹ

47

Entah profesor Anda membuat kesalahan atau Anda salah mengerti apa yang dia katakan. Dalam konteks DBMS relasional, seperti yang diterapkan oleh berbagai vendor, fungsi agregat COUNT(<expression>)mengembalikan jumlah nilai-nilai non-NULL <expression>dalam set hasil (atau grup).

Ada kasus khusus COUNT(*), yang mengembalikan jumlah baris dalam set atau grup hasil, bukan jumlah nilai apa pun. Ini setara dengan COUNT(<constant expression>), seperti COUNT(1).

Banyak basis data mendukung COUNT(DISTINCT <expression>), yang akan mengembalikan jumlah nilai unik <expression>.


13

Jika profesor Anda berbicara tentang SQL, pernyataannya salah. COUNT(x)akan mengembalikan jumlah baris di mana x IS NOT NULLtermasuk duplikat. COUNT(*) or COUNT([constant])adalah kasus khusus yang akan menghitung baris, bahkan di mana setiap kolom berada NULL. Namun, duplikat selalu dihitung, kecuali jika Anda menentukan COUNT(distinct x). Contoh:

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 tidak valid.

Sebagai catatan, NULL memperkenalkan beberapa perilaku tidak intuitif. Sebagai contoh:

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

yaitu:

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

Jika dia berbicara tentang sistem relasional seperti yang dijelaskan oleh, misalnya, buku Basis Data, Jenis, dan Model Relasional: Manifesto Ketiga oleh CJ Date dan Hugh Darwen - itu akan menjadi pernyataan yang benar.

Katakan bahwa kita memiliki hubungan:

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

sesuai dengan:

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

yaitu

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

yang akan mengembalikan 2 .


3

Ini adalah cara kerjanya di MS SQL Server

COUNT (*) mengembalikan jumlah item dalam grup. Ini termasuk nilai NULL dan duplikat.

COUNT (SEMUA ekspresi) mengevaluasi ekspresi untuk setiap baris dalam grup dan mengembalikan jumlah nilai nonnull.

COUNT (Ekspresi berbeda) mengevaluasi ekspresi untuk setiap baris dalam grup dan mengembalikan jumlah nilai unik, nonnull.


1

Jika meja tampak seperti ini,

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

Anda bisa mengharapkan permintaan untuk mengembalikan 2, setidaknya di Oracle DB, karena nol tidak dihitung. Namun duplikat dihitung dengan baik.


-7

mungkin maksudnya bersamaan dengan unik, Tapi Hitung memang COUNT DUPLICATES. Ada beberapa guru yang tidak tahu barang-barang mereka, tidak ada kekhawatiran hanya menginformasikan teman sekelas Anda / teman sehingga ketika mereka pergi ke db yang lebih tinggi dan kehidupan nyata mereka tidak akan lupa, lebih baik mengirim pesan anonim kepada guru Anda bertanya kepadanya bahwa mereka tidak memahami beberapa fungsi sql dan ingin demonstrasi, mintalah guru Anda datang dengan cara untuk kelas untuk menyarankan apa yang harus dimasukkan termasuk duplikat (tidak memiliki data yang besar) dan ketika dia menggunakan jumlah fungsi, Anda mendapatkannya. Beberapa orang akan mengambilnya, Juga ketika dia mengatakan basis data lain, mintalah teman Anda menanyakan yang mana, lalu gandakan dia dan katakan Anda mencoba semua basis data itu dan mereka tidak berfungsi seperti katanya dan menghitung mengambil duplikat.


2
Saya tidak yakin akan berangkat dengan sengaja memusuhi guru. Dengan beberapa orang, mungkin cukup memadai untuk hanya bertemu dengan mereka secara pribadi dan bertanya tentang hal itu, dengan Anda siap memberi contoh balasan (hanya untuk menunjukkan bahwa Anda punya alasan untuk bertanya). Namun, dasar-dasar pendekatan itu valid; hingga OP arah spesifik untuk digunakan.
RDFozz
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.