`COUNT` 是否丢弃重复项?

Jul*_*mur 41 dbms

我的教授教了我这个 SQL 语句:

SELECT COUNT(length) FROM product
Run Code Online (Sandbox Code Playgroud)

将返回2以下数据集:

product
|id | length | code |
|-------------------|
| 1 |    11  | X00  |
| 2 |    11  | C02  |
| 3 |    40  | A31  |
Run Code Online (Sandbox Code Playgroud)

她说这COUNT不算重复。我不同意。在尝试了很多 DBMS 之后,我从来没有发现有这种行为的。是否存在这样的 DBMS?

mus*_*cio 48

要么你的教授犯了错误,要么你误解了她说的话。在关系 DBMS 的上下文中,正如由不同供应商实现的那样,聚合函数COUNT(<expression>)返回<expression>结果集(或一组)中非 NULL 值的数量。

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

许多数据库都支持COUNT(DISTINCT <expression>),这返回<expression>.


Vad*_*aev 39

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

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

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

按照这个原则,你可能会说SELECT length FROM product已经只包含两行,因此相应的COUNT返回2,而不是3


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

SUMMARIZE product {length} BY {}: {c := COUNT()}
Run Code Online (Sandbox Code Playgroud)

给出:

相对结果

  • 老师可能在谈论一般的 DBMS,而不仅仅是 SQL DBMS。正如编辑显示的那样,有关系模型的实现(例如 Rel),其中 `COUNT` 的行为与 SQL 实现不同。 (3认同)
  • 由于我们今年晚些时候与这位教授进行了关系理论课程,我认为这是正确的答案。无论如何,我会向我的教授询问更多信息。 (2认同)

Len*_*art 14

如果您的教授在谈论 SQL,则该语句是错误的。COUNT(x)将返回 xIS 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
Run Code Online (Sandbox Code Playgroud)

COUNT(distinct *) AFAIK 无效。

作为旁注,NULL 引入了一些不直观的行为。举个例子:

SELECT SUM(x) + SUM(y),  SUM(x + y) FROM T
4, 2
Run Code Online (Sandbox Code Playgroud)

IE:

SUM(x)+SUM(y) <> SUM(x+y)
Run Code Online (Sandbox Code Playgroud)

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

假设我们有以下关系:

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
Run Code Online (Sandbox Code Playgroud)
SELECT COUNT(NAME) FROM STUDENTS
Run Code Online (Sandbox Code Playgroud)

对应于:

COUNT(STUDENTS.project(['Name']))
Run Code Online (Sandbox Code Playgroud)

IE

SELECT SUM(x) + SUM(y),  SUM(x + y) FROM T
4, 2
Run Code Online (Sandbox Code Playgroud)

这将返回2