为什么COUNT(DISTINCT(*))不起作用?

时间:2011-02-15 22:50:31

标签: sql sql-server

我仍然感到惊讶,为什么这样的简单查询无效:

SELECT COUNT(DISTINCT *) FROM dbo.t_test     

在哪里

SELECT COUNT(DISTINCT col1) FROM dbo.t_test

SELECT DISTINCT * FROM dbo.t_test 

作品。

有什么替代方案?

编辑:

DISTINCT *检查(col1,col2,...)的组合键的唯一性并返回这些行。我期望COUNT(DISTINCT *)只返回这些行的数量。我在这里错过了什么吗?

4 个答案:

答案 0 :(得分:12)

它不起作用,因为您只能根据documentationCOUNT(DISTINCT ...)中指定单个表达式:

COUNT ( { [ [ ALL | DISTINCT ] expression ] | * } )

如果仔细观察,您会发现允许的语法包含COUNT(DISTINCT *)

另一种选择是:

SELECT COUNT(*) FROM
(
    SELECT DISTINCT * FROM dbo.t_test 
) T1

答案 1 :(得分:6)

事情的真相是SQL(服务器)或任何其他SQL实现不应该在阳光下做所有事情

有理由将SQL语法限制为某些元素,从解析层到查询优化,再到结果的可预测性,只是常识。

COUNT聚合函数通常实现为具有单个项的门的流聚合,无论是*(记录计数,只是使用静态令牌),还是colname(仅限增量令牌)当不为空时)或distinct colname(一个密钥的哈希/桶)。

当你要求COUNT(DISTINCT *)或者那个问题时,COUNT(DISTINCT a,b,c) - 是的,如果某个RDBMS认为有一天能够实现它,肯定可以为你完成;但它是(1)不常见(2)向解析器添加工作(3)增加了COUNT实现的复杂性。

马克有the correct alternative

答案 2 :(得分:2)

举个简单的例子,假设您有两列,A和B.

A    B
1    100
2    100
3    100

有三个不同的A值,但只有一个不同的B值。 COUNT(DISTINCT *)不可能返回单个有意义的值。这就是为什么语法不起作用的原因。

答案 3 :(得分:2)

除了其他人所说的:

要注意的一件事是,在具有主键的表上执行count(distinct *)(如果允许)将与select count(*)相同。

这是因为 distinct * 包含PK列,因此每一行都与每隔一行不同。

因为每个非平凡的表都应该有一个主键(该规则只有非常少数例外)count(distinct *)无论如何都可以用count(*)“替换”