我仍然感到惊讶,为什么这样的简单查询无效:
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 *)只返回这些行的数量。我在这里错过了什么吗?
答案 0 :(得分:12)
它不起作用,因为您只能根据documentation在COUNT(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实现的复杂性。
答案 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(*)
“替换”