Ошибка SELECT COUNT (DISTINCT...) на нескольких столбцах?

У меня есть таблица VehicleModelYear, содержащая идентификаторы столбцов, год, марку и модель.

Следующие два запроса работают как ожидалось:

SELECT DISTINCT make, model
FROM VehicleModelYear

SELECT COUNT(DISTINCT make)
FROM VehicleModelYear

Однако этот запрос не работает

SELECT COUNT(DISTINCT make, model)
FROM VehicleModelYear

Очистить ответ - это число результатов, возвращаемых первым запросом, но просто интересно, что не так с этим синтаксисом или почему оно не работает.

Ответы

Ответ 1

COUNT() в SQL Server принимает следующий синтаксис

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

Ответ 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 ; 

И, наконец, 2-й и 3-й запрос выше изменен, без подзапросов:

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 ;

Поздние добавления @Александр Федоренко:

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 ;