为啥 COUNT(DISTINCT (*)) 不起作用?
Posted
技术标签:
【中文标题】为啥 COUNT(DISTINCT (*)) 不起作用?【英文标题】:Why doesn't COUNT(DISTINCT (*)) work?为什么 COUNT(DISTINCT (*)) 不起作用? 【发布时间】:2011-02-15 22:50:30 【问题描述】:我仍然很惊讶为什么这么简单的查询不起作用:
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 *) 只返回这样的行数。我这里有什么遗漏吗?
【问题讨论】:
【参考方案1】:它不起作用,因为您只能按照documentation 指定COUNT(DISTINCT ...)
中的单个表达式:
COUNT ( [ [ ALL | DISTINCT ] expression ] | * )
如果你仔细看你会发现允许的语法不包括COUNT(DISTINCT *)
。
替代方案是这样的:
SELECT COUNT(*) FROM
(
SELECT DISTINCT * FROM dbo.t_test
) T1
【讨论】:
【参考方案2】:事情的真相是 SQL (Server) 或任何其他 SQL 实现不应该在阳光下做所有事情。
有理由将 SQL 语法限制为某些元素,从解析层到查询优化再到结果的可预测性再到常识。
COUNT 聚合函数通常实现为带有单个项目的门的流聚合,无论是*
(记录计数,只使用静态令牌),还是colname
(仅当不为空时才增加令牌)或distinct colname
(带有一个键的哈希/桶)。
当您要求COUNT(DISTINCT *)
或就此而言,COUNT(DISTINCT a,b,c)
- 是的,如果某个 RDBMS 认为有朝一日可以实现它,那肯定可以为您完成;但它是 (1) 不常见的 (2) 增加了解析器的工作 (3) 增加了 COUNT 实现的复杂性。
马克有the correct alternative。
【讨论】:
【参考方案3】:除了其他人所说的:
需要注意的一点是,在具有主键的表上执行 count(distinct *)
(如果允许)将与 select count(*)
相同。
这是因为 distinct * 包括 PK 列,因此每一行都与其他行不同。
因为每个重要的表都应该有一个主键(该规则只有非常少数例外)count(distinct *)
无论如何都可以用count(*)
“替换”。
【讨论】:
【参考方案4】:举个简单的例子,假设您有两列,A 和 B。
A B
1 100
2 100
3 100
有三个不同的 A 值,但只有一个不同的 B 值。 COUNT(DISTINCT *)
不可能返回一个有意义的值。这就是为什么该语法不起作用的原因。
【讨论】:
谢谢乔!我更新了有关您的解释的问题。以上是关于为啥 COUNT(DISTINCT (*)) 不起作用?的主要内容,如果未能解决你的问题,请参考以下文章
Hibernate HQL Count Distinct 不起作用?
Bigquery SELECT * WHEN COUNT(DISTINCT value) 不起作用
为啥按 count(lab_results.testid) desc 排序在 C# 中不起作用 - 但在 SQL Server 中很好?