【发布时间】:2015-01-21 16:54:07
【问题描述】:
我试图从这个解决方案中实现一个中位数(除其他外,但这似乎是最简单的中位数代码):Function to Calculate Median in Sql Server
但是,我在应用它时遇到了困难。这是我当前的 SQL 查询。我的目标是在给定的周、月和部门找到CallerComplaintTypeID 的中位数TotalTimeOnCall。我认为我最大的问题是我根本不了解如何应用这个中值函数来实现我的结果。
例如,如果我需要平均值,我可以将 ORDER BY 更改为 GROUP BY,然后改为 AVG(TotalTimeOnCall)。相反,我该如何使用这个中值解决方案来实现这个想法?
这是“原始数据”查询:
WITH rawData as (
SELECT
DepartmentName
,MONTH(PlacedOnLocal) AS MonthNumber
,CASE
WHEN Datepart(day, PlacedOnLocal) < 8 THEN '1'
WHEN Datepart(day, PlacedOnLocal) < 15 THEN '2'
WHEN Datepart(day, PlacedOnLocal) < 22 THEN '3'
WHEN Datepart(day, PlacedOnLocal) < 29 THEN '4'
ELSE '5'
END AS WeekNumber
,CallerComplaintTypeID
,TotalTimeOnCall
FROM [THE_RELEVANT_TABLE]
WHERE PlacedOnLocal BETWEEN '2014-09-01' AND '2014-12-31'
AND CallerComplaintTypeID IN (5,89,9,31,203)
AND TotalTimeOnCall IS NOT NULL
)
SELECT
DepartmentName,
MonthNumber,
WeekNumber,
CallerComplaintTypeID,
TotalTimeOnCall
FROM
rawData
ORDER BY DepartmentName, MonthNumber, WeekNumber, CallerComplaintTypeID
使用此示例输出:
DepartmentName MonthNumber WeekNumber CallerComplaintTypeID TotalTimeOnCall
Dept_01 9 1 5 654
Dept_01 9 1 5 156
Dept_01 9 1 5 21
Dept_01 9 1 5 67
Dept_01 9 1 5 13
Dept_01 9 1 5 97
Dept_01 9 1 5 87
Dept_01 9 1 5 16
这是上面的中位数解:
SELECT
(
(
SELECT MAX(TotalTimeOnCall)
FROM
(
SELECT TOP 50 PERCENT TotalTimeOnCall
FROM rawData
WHERE TotalTimeOnCall IS NOT NULL
ORDER BY TotalTimeOnCall
) AS BottomHalf
)
+
(
SELECT MIN(TotalTimeOnCall)
FROM
(
SELECT TOP 50 PERCENT TotalTimeOnCall
FROM rawData
WHERE TotalTimeOnCall IS NOT NULL
ORDER BY TotalTimeOnCall DESC
) AS TopHalf
)
) / 2 AS Median
【问题讨论】:
-
该中位数方法不支持每组中位数。它只能计算整个表的中位数。您可以考虑创建一个用户定义的
MEDIAN()聚合函数。 -
另外,我怀疑基于
ROW_NUMBER()的替代方案也作为对您所链接问题的答案提出,可能适用于分组中位数,但我不准备详细说明。跨度> -
@JohnBollinger 谢谢,我能够从效果很好的东西中拼凑出一些东西。
标签: sql sql-server sql-server-2008