【问题标题】:SELECT COUNT(DISTINCT... ) error on multiple columns?多列上的 SELECT COUNT(DISTINCT...) 错误?
【发布时间】:2013-09-28 22:08:39
【问题描述】:

我有一个表 VehicleModelYear,其中包含列 id、year、make 和 model。

以下两个查询按预期工作:

SELECT DISTINCT make, model
FROM VehicleModelYear

SELECT COUNT(DISTINCT make)
FROM VehicleModelYear

但是,这个查询不起作用

SELECT COUNT(DISTINCT make, model)
FROM VehicleModelYear

很明显,答案是第一个查询返回的结果数量,但只是想知道这个语法有什么问题或者为什么它不起作用。

【问题讨论】:

标签: sql sql-server tsql


【解决方案1】:

SQL Server 中的COUNT() 接受以下语法

COUNT(*)
COUNT(colName)
COUNT(DISTINCT colName)

您可以有一个子查询,它返回一组唯一的 make 和 model,您可以使用它们。

SELECT  COUNT(*)
FROM
        (
            SELECT  DISTINCT make, model
            FROM    VehicleModelYear
        ) a

末尾的“a”不是错字。这是一个别名,没有它,SQL 将给出错误ERROR 1248 (42000): Every derived table must have its own alias。

【讨论】:

    【解决方案2】:

    尝试将它们组合成一个字段:

    SELECT COUNT(DISTINCT make + ' ' + model)
    FROM VehicleModelYear
    

    【讨论】:

    • 或SELECT COUNT(DISTINCT CHECKSUM(make, model)) FROM VehicleModelYear
    • 当我可以找到映射回列的标量表达式时,当列是字符串或易于转换时,并且当表达式中的列很少时,我使用它。它又快又脏。
    • 如果不引用字符串列,例如 int 列 - 此答案不会产生正确的值,但在执行时不会产生错误。正如@Ian Elder 的评论所述,可以强制转换列以使其正常工作。任何人都知道为什么这不会失败(对于 int 列)以及发生了什么?
    • 校验和更好,因为您不必担心投射。
    • 确保对校验和解决方案进行性能比较,而不是将多列不同的列包装到另一个子查询中并对其进行计数。
    【解决方案3】:

    语法是有效的 SQL,但尚未在 SQL-Server 中实现。

    尝试重写:

    ; WITH cte AS
      ( SELECT DISTINCT make, model
        FROM VehicleModelYear
      )
    SELECT COUNT(*) AS total
    FROM cte ; 
    

    或:

    ; WITH cte AS
      ( SELECT COUNT(DISTINCT model) AS cnt
        FROM VehicleModelYear
        GROUP BY make
      )
    SELECT SUM(cnt) AS total
    FROM cte ; 
    

    或:

    ; WITH cte AS
      ( SELECT NULL AS n
        FROM VehicleModelYear
        GROUP BY make, model
      )
    SELECT COUNT(*) AS total
    FROM cte ; 
    

    最后,修改了上面的第二个和第三个查询,没有子查询:

    SELECT DISTINCT
        SUM(COUNT(DISTINCT model)) OVER () AS total
    FROM VehicleModelYear
    GROUP BY make ;
    
    SELECT DISTINCT COUNT(*) OVER () AS total
    FROM VehicleModelYear
    GROUP BY make, model ;
    

    @Alexander Fedorenko 的后期添加:

    SELECT TOP (1)
        SUM(COUNT(DISTINCT model)) OVER () AS total
    FROM VehicleModelYear
    GROUP BY make ;
    
    SELECT TOP (1) COUNT(*) OVER () AS total
    FROM VehicleModelYear
    GROUP BY make, model ;
    

    或:

    ; WITH cte AS
      ( SELECT DENSE_RANK() OVER(ORDER BY make, model) AS dr
        FROM VehicleModelYear
      )
    SELECT MAX(dr) AS total
    FROM cte ;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-01-27
      • 2015-01-28
      • 1970-01-01
      • 2017-12-19
      • 1970-01-01
      • 2012-05-10
      • 2023-03-15
      相关资源
      最近更新 更多