为啥 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 不起作用?

为啥 DISTINCT 在这种情况下不起作用? (SQL)

Bigquery SELECT * WHEN COUNT(DISTINCT value) 不起作用

为啥按 count(lab_results.testid) desc 排序在 C# 中不起作用 - 但在 SQL Server 中很好?

sql动态拼接:为啥select count(*) where条件后面<if test="">不起作用?

count和distinct