【问题标题】: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 *) 只返回这样的行数。我这里有什么遗漏吗?

【问题讨论】:

    标签: sql sql-server


    【解决方案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 *) 不可能返回一个有意义的值。这就是为什么该语法不起作用的原因。

          【讨论】:

          • 谢谢乔!我更新了有关您的解释的问题。
          猜你喜欢
          • 2020-04-05
          • 2013-09-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-12-08
          • 1970-01-01
          • 2017-12-19
          • 1970-01-01
          相关资源
          最近更新 更多