2011-02-15 68 views
2

我仍然惊讶为什么这么简单的查询是不工作:为什么COUNT(DISTINCT(*))不起作用?

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 *)只返回这样的行数。我在这里错过了什么吗?

回答

3

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

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

COUNT聚合函数与对单个项目的栅极流聚集正常开展的,是它*(记录数,只需使用一个静态的令牌),或colname(增量令牌只有当不为空)或distinct colname(一个密钥的哈希/桶)。

当你询问COUNT(DISTINCT *)或者- 是的,如果某些关系型数据库管理系统认为适合于某一天实施它,那么肯定会为你完成;但是(1)很少见(2)为解析器添加了工作(3)增加了COUNT实现的复杂性。

马克有the correct alternative

+0

+1谢谢。很好的回答! – rkg 2011-02-15 23:26:32

10

它不工作,因为你只能在COUNT(DISTINCT ...)指定一个表达式为每documentation

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

如果你仔细看,你可以看到,在允许的语法包括COUNT(DISTINCT *)

另一种方法是这样的:

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

+1很好的答案。 – RobertPitt 2011-02-15 22:55:50

2

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

A B 
1 100 
2 100 
3 100 

有三种不同的A值,但只有一个不同B值。 COUNT(DISTINCT *)将不可能返回单个有意义的值。这就是为什么该语法无法工作。

+0

谢谢乔!我更新了有关您的解释的问题。 – rkg 2011-02-15 23:02:08

2

除了什么其他人说:

有一点要注意的是,这样做,因为它有主键可以等同于一个select count(*)表中的count(distinct *)(如果被允许)。

这是因为distinct *包含PK列,因此每行都不同于其他行。

成为每一个不平凡的表应该有一个主键(只有非常少数例外情形规则)count(distinct *)可以“改为”与count(*)反正。