我的教授教了我这个SQL语句:
SELECT COUNT(length) FROM product

将返回带有以下数据集的2
product
|id | length | code |
|-------------------|
| 1 |    11  | X00  |
| 2 |    11  | C02  |
| 3 |    40  | A31  |

她通过说COUNT不计算重复项来证明这一点。我不同意在尝试了许多DBMS之后,我再也没有找到具有这种行为的数据库管理系统。这样的DBMS是否存在?

评论

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

#1 楼

COUNT确实在我知道的所有DBMS中都包含重复项。


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



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

遵循此原理,您可以说SELECT length FROM product已经仅包含两行,因此相应的COUNT返回2 ,而不是3。例如,在Rel DBMS中,使用问题和教程D语法给出的关系:

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


给定:



评论


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

–朱尔斯·拉穆尔
17年8月2日在22:37

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

–超立方体ᵀᴹ
17年8月4日,11:59



#2 楼

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

COUNT(*)有一个特例,它返回结果集或组中的行数,而不是任何值的数目。这等效于COUNT(<constant expression>),例如COUNT(1)

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

#3 楼

如果您的教授在谈论SQL,那么该陈述是错误的。 COUNT(x)将返回x x4312079q包含重复项的行数。 IS NOT NULL是一种特殊情况,它将对行进行计数,即使每一列都是COUNT(*) or COUNT([constant])的行也是如此。但是,除非指定NULL,否则始终计入重复项。示例:

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 x)无效的AFAIK。

作为补充,NULL引入了一些不直观的行为。例如:

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


ie:

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


如果他/她在谈论关系系统例如CJ Date和Hugh Darwen所著的《数据库,类型和关系模型:第三宣言》一书所描述的-这将是正确的陈述。

假设我们具有以下关系:

 COUNT(distinct *) 




SELECT COUNT(NAME) FROM STUDENTS


对应于:

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


ie

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


将返回2。

#4 楼

这是它在MS SQL Server中的工作方式。COUNT(*)返回组中的项目数。这包括NULL
值和重复项。

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

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


#5 楼

如果该表看起来像这样,您可以期望查询至少在Oracle DB中返回2,因为不计算空值。但是重复算是很好。

#6 楼

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

评论


我不确定我是否会故意与老师对抗。与一些人在一起,只要准备好反例就足够了,只是亲自与他们见面并提出要求(只是为了表明您有问的理由)。尽管如此,该方法的基础还是有效的。取决于OP的特定使用方向。

–RDFozz
17年8月4日14:33