随时间推移的中位数 - SQL Server

时间:2018-04-20 18:03:26

标签: sql sql-server median dense-rank

我有数据(确切地说是支持票据统计数据),我试图获得中位数,随着时间的推移。

现在,我有一个查询,用于计算故障单打开日期与关闭日期之间的差异。我使用内置AVG功能的SQL Server,获取数据并将平均天数转为一系列数月和数年。这很有效,但我发现由于数据中的异常值导致指标偏差。

我真正想要的是数据的中位数,数月和数年。我无法实现我所追求的目标,如果可能的话,我并不积极。

我现在使用AVG功能的查询是:

SELECT 'Support - Days To Close Escalation', *
FROM
(
    SELECT 
        DATEDIFF(HOUR, e.CreatedDate, e.Escalation_Close_Date_Time__c) AS DaysToCloseEscalation,                        
        LEFT(CONVERT(CHAR(10), e.CreatedDate,126), 7) AS EscalationCreateDate
    FROM [dbo].[Escalations] AS e WITH(NOLOCK)

    LEFT JOIN [dbo].[Case] AS c WITH(NOLOCK)
    ON e.Case__c = c.Id

    WHERE e.Escalation_Queue__c IN ('PM 10 Tier 2 Support', 'PM 11 Tier 2 Support')
    AND e.CreatedDate BETWEEN '2017-04-01 00:00:00.000' AND '2018-04-01 00:00:00.000'
    AND e.Escalation_Close_Date_Time__c IS NOT NULL

) AS SupportEscalationVolume
PIVOT
(
    AVG(SupportEscalationVolume.DaysToCloseEscalation) FOR SupportEscalationVolume.EscalationCreateDate IN ([2017-04],[2017-05],[2017-06],[2017-07],[2017-08],[2017-09],[2017-10],[2017-11],[2017-12],[2018-01],[2018-02],[2018-03])
) AS SupportEscalationVolumePivot

此查询的结果类似于(除了所有在一行中,因为数据是透视的):

StatDescription | Support - Days To Close Escalation
----------------------------------------------------
2017-04         | 107   
2017-05         | 52    
2017-06         | 101   
2017-07         | 106   
2017-08         | 69    
2017-09         | 54    
2017-10         | 49    
2017-11         | 42    
2017-12         | 51    
2018-01         | 31    
2018-02         | 23    
2018-03         | 15

经过一些关于如何在SQL中提取中位数的研究之后,我已经使用了DENSE_RANK(),如下面的查询所示。我从ROW_NUMBER()开始,但是这给了我一个所有记录的计数器,我真正想要的是每个月/每年分组关闭票证的时间的中位数。

;
WITH SupportDaysToClose(HoursToCloseEscalation, EscalationCreateDate, RowNumber)
AS
(
    SELECT 
        DATEDIFF(HOUR, e.CreatedDate, e.Escalation_Close_Date_Time__c) AS HoursToCloseEscalation,                       
        LEFT(CONVERT(CHAR(10), e.CreatedDate,126), 7) AS EscalationCreateDate,
        DENSE_RANK() OVER(ORDER BY LEFT(CONVERT(CHAR(10), e.CreatedDate,126), 7) ASC) AS RowNumber
    FROM [dbo].[Escalations] AS e WITH(NOLOCK)

    LEFT JOIN [dbo].[Case] AS c WITH(NOLOCK)
    ON e.Case__c = c.Id

    WHERE e.Escalation_Queue__c IN ('PM 10 Tier 2 Support', 'PM 11 Tier 2 Support')
    AND e.CreatedDate BETWEEN '2017-04-01 00:00:00.000' AND '2018-04-01 00:00:00.000'
    AND e.Escalation_Close_Date_Time__c IS NOT NULL

)

SELECT *
FROM SupportDaysToClose
ORDER BY RowNumber,HoursToCloseEscalation

此数据的示例如下

HoursToClose|CreateDate|RowNumber
---------------------------------
0           |2017-04   |1
7           |2017-08   |5
27          |2017-12   |9

每个RowNumber与给定的月份和年份相关联,最大值为12。

此时,我不确定该去哪里。

以前有没有人做过这样的事情?我不确定我是否走在正确的轨道上,或者我是否需要重新考虑整个战略。如果语法很难遵循,我会提前道歉。

0 个答案:

没有答案