Profesörüm bana 'COUNT' un kopya saymadığını öğretti


40

Üniversitede profesörüm bana bu SQL ifadesinin şu şekilde olduğunu söyledi:

SELECT COUNT(length) FROM product

2aşağıdaki veri kümesiyle dönecektir :

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

O COUNTyineleme sayılmaz diyerek haklı çıktı .

Profesörüme bir hata yaptığını düşündüğümü söyledim. Bazı DBMS'lerin kopyaları sayıp saymayacağını ya da saymayacağını söyledi.

Çok fazla sayıda DBMS denedikten sonra, bu davranışa sahip birini bulamadım.

Bu DBMS var mı?

Bir profesörün bu davranışı öğretmesi için herhangi bir sebep var mı? Ve diğer DBMS'lerin farklı davranabileceğini bile söylemeden?


Bilginize, kurs desteği burada (fransızca) mevcuttur . Söz konusu slayt, sayfa 10'da sol alt köşededir.


1
Slaytlar ANSi SQL hakkında konuştuğundan, profesörünüz yanlıştır, 1992 standardında bile (bkz. Sayfa 125, katkıda. Andrew.cmu.edu/~shadow/sql/sql1992.txt ) DISTINCT olan ve olmayan sayım için çeşitli davranışları listeler. Güncellenmiş bir versiyon olan tonda (ALL / OVER gibi daha fazla seçenek içeren) kütüphaneyi ziyaret etmek isteyebilirsiniz
saat

Yanıtlar:


38

COUNT Farkında olduğum tüm DBMS'lerdeki kopyaları saymaz, fakat.

Bir profesörün bu davranışı öğretmesi için herhangi bir sebep var mı?

Evet, bir sebebi var. (Tüm modern ilişkisel DBMSes temelini) orijinal ilişkisel Teoride ilişki bir olan dizi bu kelimenin matematiksel anlamda. Bu, hiçbir ilişkinin sadece “tablolarınızı” değil, tüm geçiş ilişkilerini de içeren kopyaları içeremeyeceği anlamına gelir.

Bu prensibi izleyerek SELECT length FROM productzaten sadece iki satır içerdiğini söyleyebilirsiniz , dolayısıyla karşılık gelen COUNTgetirileri 2değil 3.


Örneğin, Rel DBMS'de, soruda verilen ilişkiyi ve Öğretici D sözdizimini kullanarak:

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

verir:

Rel sonucu


1
Bu sene daha sonra bu profesörle ilişkisel teori dersleri aldığımızdan, bunun doğru cevap olduğunu düşünüyorum. Neyse, profesörümden daha fazla bilgi isteyeceğim.
Jules Lamur

2
Öğretmen belki sadece DBMS'ler hakkında değil DBMS'ler hakkında konuşuyordu. Düzenlemenin gösterdiği gibi, COUNTSQL uygulamalarından farklı şekilde davranan ilişkisel model (örneğin, Rel) uygulamaları vardır.
ypercubeᵀᴹ

47

Ya profesörünüz bir hata yaptı ya da ne dediğini yanlış anladınız. İlişkisel DBMS'ler bağlamında, çeşitli satıcılar tarafından uygulandığı gibi, toplama işlevi sonuç kümesindeki (veya bir gruptaki) COUNT(<expression>)NULL olmayan değerlerin sayısını döndürür <expression>.

Sonuç kümesindeki veya gruptaki satırCOUNT(*) sayısını döndüren özel bir durum var, hiçbir şeyin değerinin sayısını değil. Bu eşdeğerdir gibi .COUNT(<constant expression>)COUNT(1)

Birçok veritabanları destekleyen COUNT(DISTINCT <expression>), hangi olacak benzersiz değerlerinin sayısını döndürür <expression>.


13

Profesörünüz SQL hakkında konuşuyorsa, ifade yanlıştır. COUNT(x)x IS NOT NULLdahil yinelenenleri içeren satır sayısını döndürür . COUNT(*) or COUNT([constant])Her sütunun olduğu yerde bile satırları sayan özel bir durumdur NULL. Ancak, siz belirtmedikçe, kopyalar her zaman sayılır COUNT(distinct x). Örnek:

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 *) geçersiz AFAIK.

Not olarak, NULL bazı sezgisel davranışlar ortaya koymaktadır. Örnek olarak:

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

yani:

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

Örneğin, Veritabanları, Tipler ve İlişkisel Model kitabı : CJ Date ve Hugh Darwen'in Üçüncü Manifestosu kitabı tarafından tarif edildiği gibi bir ilişkisel sistemden bahsediyorsa - bu doğru bir ifade olacaktır.

Diyelim ki ilişkimiz var:

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

karşılık gelir:

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

yani

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

2 dönecekti .


3

MS SQL Server'da bu şekilde çalışır.

COUNT (*), bir gruptaki öğelerin sayısını döndürür. Bu NULL değerleri ve kopyaları içerir.

COUNT (ALL expression), bir gruptaki her satır için ifadeyi değerlendirir ve boş olmayan değerlerin sayısını döndürür.

COUNT (DISTINCT ifadesi), bir gruptaki her satır için ifadeyi değerlendirir ve benzersiz, boş olmayan değerlerin sayısını döndürür.


1

Eğer masa böyle olsaydı,

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

boş sayılmazsa, en azından Oracle DB'de sorgunun 2 döndürmesini bekleyebilirsiniz. Yinelemeler ancak iyi sayılır.


-7

belki benzersiz ile birlikte demek istiyor, ama Sayı yapar COUNT DUPLICATES. Eşyalarını bilmeyen bazı öğretmenler var, endişelenmenize gerek yok sadece sınıf arkadaşlarınızı / arkadaşlarınızı bilgilendirin, böylece daha yüksek db ve gerçek hayata gittiklerinde unutamayacaklar, öğretmeninize, bilmediklerini söyleyen isimsiz bir mesaj gönderin. Sql işlevlerinden bazılarını anlayın ve bir gösteri isteyin, öğretmeninize sınıfın neleri ekleyeceğini önermek için bir yol bulmasını sağlayın (veriler büyük olmasın) ve işlev sayısını kullandığında onu aldınız. Bazı insanlar bunu yakalayacak, Ayrıca diğer veritabanlarını söylediğinde, arkadaşına ona hangilerini sormasını söyle, sonra da onu iki katına çıkar ve tüm bu veritabanlarını denediğini ve söylediği gibi çalışmadığını ve sayının çiftleri topladığını söyledi.


2
Öğretmeni kasten kızdırmak için yola çıkacağımdan emin değilim. Bazılarında, yalnızca onlarla şahsen tanışmak ve bunu sormak tamamen yeterli olabilir, size karşı örnek hazır (sadece sormak için bir nedeniniz olduğunu göstermek için). Yine de, yaklaşımın temelleri geçerlidir; OP'ye kadar kullanılacak belirli yöne doğru.
RDFozz
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.