2013-09-23 1 views
16

Ho una tabella, VehicleModelYear, contenente id colonne, anno, marca e modello.SELECT COUNT (DISTINCT ...) errore su più colonne?

Le due query seguenti funzionano come previsto:

SELECT DISTINCT make, model 
FROM VehicleModelYear 

SELECT COUNT(DISTINCT make) 
FROM VehicleModelYear 

Tuttavia, questa query non funziona

SELECT COUNT(DISTINCT make, model) 
FROM VehicleModelYear 

E 'chiaro che la risposta è il numero di risultati restituiti dalla prima query, ma mi chiedo cosa c'è di sbagliato in questa sintassi o perché non funziona.

+0

possibile duplicato [Counting DISTINCT su più colonne ] (http://stackoverflow.com/questions/1471250/counting-distinct-over-multiple-c olumns) –

risposta

32

COUNT() nel SQL Server accetta la seguente sintassi

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

Si può avere un subquery che restituisce serie unica di make e model che si può contare con.

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

"A" alla fine non è un errore di battitura. È un alias senza il quale SQL darà un errore ERROR 1248 (42000): Every derived table must have its own alias.

+0

funziona anche in MySQL, grazie! – by0

5

La sintassi è SQL valida ma non è stata implementata in SQL Server.

Prova una riscrittura:

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

o:

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

o:

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

E, infine, il 2 e 3 query di cui sopra modificato, senza sottointerrogazioni:

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 ; 

aggiunte tardivi da @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 ; 

o:

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

Ha senso, grazie! – csab

18

Prova loro combinazione in un singolo campo:

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

'' '') –

+9

o 'SELEZIONA CONTEGGIO (DISTINCT CHECKSUM (marca, modello)) DA VehicleModelYear' –

+0

@TimSchmelter neat! –