Мій професор навчив мене, що "COUNT" не рахує дублікатів


40

В університеті мене професор цього року навчив мене, що це твердження SQL:

SELECT COUNT(length) FROM product

повернеться 2із таким набором даних:

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

Вона виправдала це тим, що COUNTне рахує дублікатів.

Я сказав своєму професору, що вважаю, що вона помилилася. Вона відповіла мені, що деякі СУБД можуть чи не можуть рахувати дублікати.

Перепробувавши багато СУБД, я жодного разу не знайшов такої поведінки.

Чи існує ця СУБД?

Чи є причина, щоб професор навчав такої поведінки? І навіть не згадуючи, що інші СУБД можуть поводитися інакше?


FYI, підтримка курсу доступна тут (французькою мовою) . Відповідний слайд знаходиться в нижньому лівому куті на сторінці 10.


1
Оскільки слайди говорять про ANSi SQL, ваш професор помиляється, навіть у стандарті 1992 року (див. Сторінку 125 тут contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt ) перераховано різні форми поведінки для підрахунку з і без DISTINCT. Можливо, ви захочете відвідати бібліотеку, щоб змінити оновлену версію (яка включає в себе більше варіантів, як ALL / OVER)
eckes

Відповіді:


38

COUNT рахує дублікати у всіх СУБД, про які я знаю, але.

Чи є причина, щоб професор навчив цю поведінку

Так, є причина. У оригінальній теорії реляції (яка лежить в основі всіх сучасних реляційних СУБД) співвідношення - це множина в математичному сенсі цього слова. Це означає, що жодне відношення не може містити дублікатів взагалі, включаючи всі перехідні відносини, а не лише ваші "таблиці".

Дотримуючись цього принципу, ви можете сказати, що SELECT length FROM productвже містить лише два рядки, отже, відповідні COUNTповернення 2, а не 3.


Наприклад, у СУБД Rel , використовуючи відношення, задане у питанні та синтаксисі D Підручник :

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

дає:

Rel результат


1
Оскільки ми з цим професором провели курси реляційної теорії пізніше цього року, я вважаю, що це правильна відповідь. У всякому разі, я попрошу у свого професора більше інформації.
Жуль Ламур

2
Вчитель, можливо, говорив про СУБД взагалі, а не лише про СУБД. Як показує редакція, є реалізація реляційної моделі (наприклад, Rel), де COUNTповодиться інакше, ніж реалізація SQL.
ypercubeᵀᴹ

47

Або ваш професор помилився, або ви неправильно зрозуміли, що вона сказала. У контексті реляційних СУБД, реалізованих різними постачальниками, функція агрегату COUNT(<expression>)повертає кількість не-NULL значень <expression>у наборі результатів (або групі).

Існує особливий випадок COUNT(*), який повертає кількість рядків у наборі результатів чи групі, а не кількість значень нічого. Це еквівалентно COUNT(<constant expression>), наприклад, як COUNT(1).

Багато баз даних підтримують COUNT(DISTINCT <expression>), яка буде повертати кількість унікальних значень <expression>.


13

Якщо ваш професор говорить про SQL, це твердження неправильне. COUNT(x)поверне кількість рядків, де х, IS NOT NULLвключаючи дублікати. COUNT(*) or COUNT([constant])це особливий випадок, який буде рахувати рядки, навіть ті, де є кожен стовпець NULL. Однак дублікати завжди підраховуються, якщо не вказати COUNT(distinct x). Приклад:

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.

Як бічна примітка, NULL вводить деяку неінтуїтивну поведінку. Як приклад:

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

тобто:

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

Якщо він / вона говорить про реляційну систему, як описано, наприклад, у книзі Бази даних, типи та реляційна модель: Третій маніфест від CJ Date та Х'ю Дарвена - це було б правильним твердженням.

Скажіть, що ми маємо відношення:

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

відповідає:

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

тобто

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

який би повернув 2 .


3

Ось як це працює в MS SQL Server

COUNT (*) повертає кількість елементів у групі. Сюди входять значення NULL та дублікати.

COUNT (ВСЕ вираження) оцінює вираз для кожного рядка групи та повертає кількість ненульових значень.

COUNT (вираз DISTINCT) оцінює вираз для кожного рядка групи та повертає кількість унікальних ненульових значень.


1

Якби стіл виглядав так,

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

можна очікувати, що запит поверне 2, принаймні, в БД Oracle, оскільки нулі не враховуються. Дублікати, однак, зараховуються до штрафу.


-7

можливо, вона має на увазі у поєднанні з унікальним, але граф ДУПЛІКАТИ ДІЄ. Є деякі вчителі, які не знають своїх речей, не хвилюйтесь, просто повідомте своїх однокласників / друзів, щоб, коли вони перейшли до вищого рівня та реального життя, вони не забудуть, ще краще надішліть анонімне повідомлення вашому вчителеві з проханням, щоб вони цього не зробили розумієте деякі функції sql і хочете демонстрації, чи запропонуйте вашому вчителю спосіб запропонувати класу запропонувати, що потрібно вставити, включаючи дублікати (не маючи даних бути великими), і коли вона використовує кількість функцій, ви її отримали. Деякі люди забиратимуть її. Також, коли вона каже інші бази даних, попросіть вашого друга запитати її, а потім подвійне схопити її і сказати, що ви спробували всі ці бази даних, і вони не працюють, як вона сказала, і що кількість підбирає дублікати.


2
Я не впевнений, що мав би намір навмисно протидіяти вчителя. З деякими може бути цілком адекватним лише зустрітися з ними особисто і запитати про це, готовий вам зустрічний приклад (просто щоб показати, що у вас є причина просити). Все-таки основи підходу справедливі; до ОП конкретний напрямок для використання.
RDFozz
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.