我的教授告诉我,“ COUNT”不算重复项


40

在大学里,我的教授今年教我这个SQL语句:

SELECT COUNT(length) FROM product

将返回2以下数据集:

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

她说COUNT不算重复,以此为证。

我告诉我的教授,我认为她做错了。她回答我,某些DBMS可能会或可能不会计算重复项。

在尝试了许多DBMS之后,我再也没有找到具有这种行为的数据库管理系统。

该DBMS是否存在?

教授有什么理由教这种行为吗?甚至不提其他DBMS的行为可能有所不同?


仅供参考,此处提供课程支持(法语)。有关的幻灯片在第10页的左下角。


1
由于幻灯片讨论的是ANSi SQL,因此您的教授是错误的,即使在1992年标准中(请参见第125页,此处contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt)也列出了使用DISTINCT和不使用DISTINCT进行计数的各种行为。您可能需要访问图书馆,以更新版本的形式(包含更多选项,如ALL / OVER)
eckes

Answers:


38

COUNT 确实在我知道的所有DBMS中计算重复项,但是。

教授有什么理由教这种行为吗

是的,这是有原因的。在原始的关系理论(所有现代关系DBMS的基础)中,关系是该词的数学意义上的集合。这意味着任何关系都不能包含重复项,包括所有过渡关系,而不仅仅是您的“表”。

遵循这一原理,您可以说SELECT length FROM product已经只包含两行,因此对应的COUNT返回值2不是3


例如,在Rel DBMS中,使用问题和Tutorial D语法中给出的关系:

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

给出:

相关结果


1
由于我们今年晚些时候与这位教授开设了关系理论课程,所以我认为这是正确的答案。无论如何,我会向我的教授询问更多信息。
朱尔斯·拉莫尔

2
老师可能在谈论的是DBMS,而不仅仅是SQL DBMS。如编辑所示,存在关系模型的实现(例如Rel),其COUNT行为与SQL实现不同。
ypercubeᵀᴹ

47

您的教授犯了一个错误,或者您误解了她说的话。在关系DBMS的上下文中(由各种供应商实现),聚合函数COUNT(<expression>)返回<expression>结果集(或组)中非NULL值的数量。

有一种特殊情况COUNT(*),它返回结果集中或组中的数,而不是任何值的数目。这相当于COUNT(<constant expression>),例如COUNT(1)

许多数据库支持COUNT(DISTINCT <expression>)它将返回的唯一值的数量<expression>


13

如果您的教授正在谈论SQL,那么该陈述是错误的。COUNT(x)将返回其中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和Hugh Darwen 所著的《数据库,类型和关系模型:第三宣言》所述,那将是正确的说法。

说我们有关系:

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(ALL expression)计算组中每一行的表达式,并返回非空值的数量。

COUNT(DISTINCT表达式)计算组中每一行的表达式,并返回唯一,非空值的数量。


1

如果桌子看起来像这样

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

您可能期望查询至少在Oracle DB中返回2,因为不计算空值。但是重复算是很好的。


-7

也许她的意思是与唯一性结合使用,但是Count却有COUNT个重复项。有些老师不了解自己的知识,不用担心,只是通知您的同学/朋友,这样当他们继续上更高的分贝和现实生活时,他们不会忘记,最好还是向您的老师发送匿名消息,问她他们没有了解一些sql函数并希望进行演示,让您的老师为班级提供一种方法,以建议要插入的内容包括重复项(数据不大),并且当她使用函数计数时,您就知道了。有人会继续使用该数据库。另外,当她说其他数据库时,请您的朋友问她哪些数据库,然后将她圈套两次,并说您尝试了所有这些数据库,但它们却无法像她所说的那样工作,并且该计数会重复。


2
我不确定我是否会故意与老师对抗。与一些人在一起,只要准备好反例就足够了,只是亲自与他们会面并问一下就可以了(只是表明您有要问的理由)。尽管如此,该方法的基础还是有效的。取决于OP的特定使用方向。
RDFozz
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.