2013-10-23 10 views
5

Mi piacerebbe utilizzare la funzione percentile_cont per ottenere valori mediani in T-SQL. Tuttavia, ho anche bisogno di ottenere valori medi. Mi piacerebbe fare qualcosa di simile al seguente:Usa percentile_cont con una statistica "group by" in T-SQL

SELECT CustomerID , 
    AVG(Expenditure) AS MeanSpend , percentile_cont 
    (.5) WITHIN GROUP(ORDER BY Expenditure) OVER() AS MedianSpend 
FROM Customers 
GROUP BY CustomerID 

Questo può essere realizzato? So che posso usare la clausola OVER per raggruppare i risultati percentile_cont ...

ma poi sono bloccato usando due query, no?

+0

Hai provato? Penso che funzioni. – RBarryYoung

+0

L'ho provato. Ecco l'errore ... La colonna "Spesa" non è valida nell'elenco di selezione perché non è contenuta in una funzione di aggregazione o nella clausola GROUP BY. –

risposta

4

Appena capito ... devi abbandonare il gruppo e assegnare a entrambe le funzioni di aggregazione un'istruzione eccessiva.

SELECT CustomerID, 
    AVG(Expenditure) OVER(PARTITION BY CustomerID) AS MeanSpend, 
    percentile_cont(.5) WITHIN GROUP(ORDER BY Expenditure) OVER(PARTITION BY CustomerID) AS MedianSpend 
FROM Customers 
+1

Se hai più di una riga nel tuo gruppo, restituirà i duplicati. E se hai solo una riga per gruppo, non hai bisogno di nessuna di queste funzioni. – jumxozizi

0

Non è possibile utilizzare "gruppo per" con le funzioni della finestra. Queste funzioni restituiscono i valori aggregati per ogni riga. Un modo è utilizzare "seleziona distinto" per sbarazzarsi delle righe duplicate. Assicurati di partizionare ogni funzione della finestra con le colonne non aggregate (groupId in questo esempio).

--Generate test data 
SELECT TOP(10) 
    value.number%3 AS groupId 
, value.number AS number 
INTO #data 
FROM master.dbo.spt_values AS value 
WHERE value."type" = 'P' 
ORDER BY NEWID() 
; 

--View test data 
SELECT * FROM #data ORDER BY groupId,number; 

--CALCULATE MEDIAN 
SELECT DISTINCT 
    groupId 
, AVG(number)           OVER(PARTITION BY groupId) AS mean 
, percentile_cont(.5) WITHIN GROUP(ORDER BY number) OVER(PARTITION BY groupId) AS median 
FROM #data 
; 

--Clean up 
DROP TABLE #data;