2015-12-14 107 views
0

我需要計算查詢中幾個字段的中位數,並將其按列中的一個進行分組。有沒有一種方法可以在SQL Server 2008 R2中輕鬆計算中值?我在計算2008 R2時遇到了麻煩。在SQL Server 2008 R2中計算中位數

Table structure: 
PatientName (need to calculate count group by PatientType) 
PatientType (should be used to group the query by), 
minutes1, 
minutes2, 
minutes3, 
minutes4, 
minutes5 

End Result: 
PatientCount (Group by PatientType), 
Median For minutes1 (Group by PatientType), 
Median For minutes2 (Group by PatientType), 
Median For minutes3 (Group by PatientType), 
Median For minutes4 (Group by PatientType), 
Median For minutes5 (Group by PatientType) 
+1

很容易,沒有。但這是可以完成的。您可以使用PERCENTILE_DISC,但直到2012年纔可以使用。即便如此,我也不確定這是否是真正的中位數,還是使用偶數集中最接近的較小值。例如,給定值1,3,5,7的中位數是4,但是3會足夠接近你嗎? –

+0

在過去,我使用了PERCENTILE_DISC或PERCENTILE_CONT,但它們僅在2012年或以上時纔有用。另外,我需要一個真正的中位數。 – NonProgrammer

回答

2

你可以試試這個:

SELECT PatientType, minutes1=(
    SELECT AVG(1.0 * minutes1) 
    FROM 
    (
    SELECT t3.minutes1, rn = ROW_NUMBER() OVER (ORDER BY t3.minutes1), c.c 
    FROM (SELECT minutes1 FROM Table t2 WHERE t1.PatientType=t2.PatientType) t3 
    CROSS JOIN (SELECT c = COUNT(*) FROM (SELECT minutes1 FROM Table t2 WHERE t1.PatientType=t2.PatientType) t4) AS c 
) AS x 
    WHERE rn IN ((c + 1)/2, (c + 2)/2) 
), minutes2=(
    SELECT AVG(1.0 * minutes2) 
    FROM 
    (
    SELECT t3.minutes2, rn = ROW_NUMBER() OVER (ORDER BY t3.minutes1), c.c 
    FROM (SELECT minutes2 FROM Table t2 WHERE t1.PatientType=t2.PatientType) t3 
    CROSS JOIN (SELECT c = COUNT(*) FROM (SELECT minutes2 FROM Table t2 WHERE t1.PatientType=t2.PatientType) t4) AS c 
) AS x 
    WHERE rn IN ((c + 1)/2, (c + 2)/2) 
), minutes3=(
    SELECT AVG(1.0 * minutes1) 
    FROM 
    (
    SELECT t3.minutes3, rn = ROW_NUMBER() OVER (ORDER BY t3.minutes1), c.c 
    FROM (SELECT minutes3 FROM Table t2 WHERE t1.PatientType=t2.PatientType) t3 
    CROSS JOIN (SELECT c = COUNT(*) FROM (SELECT minutes3 FROM Table t2 WHERE t1.PatientType=t2.PatientType) t4) AS c 
) AS x 
    WHERE rn IN ((c + 1)/2, (c + 2)/2) 
), minutes4=(
    SELECT AVG(1.0 * minutes4) 
    FROM 
    (
    SELECT t3.minutes1, rn = ROW_NUMBER() OVER (ORDER BY t3.minutes1), c.c 
    FROM (SELECT minutes4 FROM Table t2 WHERE t1.PatientType=t2.PatientType) t3 
    CROSS JOIN (SELECT c = COUNT(*) FROM (SELECT minutes4 FROM Table t2 WHERE t1.PatientType=t2.PatientType) t4) AS c 
) AS x 
    WHERE rn IN ((c + 1)/2, (c + 2)/2) 
), minutes5=(
    SELECT AVG(1.0 * minutes5) 
    FROM 
    (
    SELECT t3.minutes1, rn = ROW_NUMBER() OVER (ORDER BY t3.minutes1), c.c 
    FROM (SELECT minutes5 FROM Table t2 WHERE t1.PatientType=t2.PatientType) t3 
    CROSS JOIN (SELECT c = COUNT(*) FROM (SELECT minutes5 FROM Table t2 WHERE t1.PatientType=t2.PatientType) t4) AS c 
) AS x 
    WHERE rn IN ((c + 1)/2, (c + 2)/2) 
) 
FROM Table t1 
GROUP BY PatientType 

,並有可能是一個更好的方法,它有可能成爲優化了不少。

+0

如果我這些字段有空值怎麼辦?在計算中位數時,你會建議用零代替零值還是不將它們計算在我的計算中? – NonProgrammer

+1

我預計計算中位數時不會考慮空值,但這完全取決於您的空值在數據庫中的含義。 –