在 SQL Server 2008 R2 中计算中位数

Calculating Median in SQL Server 2008 R2

我需要计算查询中多个字段的中位数,并将其按其中一列分组。在 SQL Server 2008 R2 中有没有一种方法可以轻松计算中位数?我在 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)

你可以试试这个:

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

可能还有更好的方法,而且可能会优化很多。