2017-08-30 521 views
0

我正在计算呼叫中心呼叫量在一周中同一天的6周移动平均值。6周在同一天的移动平均数

我的意思是相同的6前几天(最近6个星期二,去年6个星期三等)

我有下面的代码的工作,但不灵活可言:

SELECT 
    [ROW_DATE], 
    [DEPARTMENT_DESC], 
    [totalcalls], 
    AVG([TOTALCALLS]) OVER(ORDER BY [DEPARTMENT_DESC], 
            [ROW_DATE] ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS [MOVING_AVG] 
FROM 
(
    SELECT 
     [ROW_DATE] AS [ROW_DATE], 
     [DEPARTMENT_DESC] AS [DEPARTMENT_DESC], 
     SUM([CALLS_OFFERED_ACTUALS]) AS [TOTALCALLS] 
    FROM [GEMDB].[dbo].[V_PRD_ACT_HSPLIT_intradayLCWcallsTable] 
    WHERE ROW_DATE IN(CONVERT(DATE, GETDATE() - 42), CONVERT(DATE, GETDATE() - 7), CONVERT(DATE, GETDATE() - 14), CONVERT(DATE, GETDATE() - 21), CONVERT(DATE, GETDATE() - 28), CONVERT(DATE, GETDATE() - 35)) 
    AND [DEPARTMENT_DESC] = 'techops' 
    GROUP BY 
     ROW_DATE, 
     [DEPARTMENT_DESC] 
) AS tbl 
ORDER BY 
    ROW_DATE, 
    [DEPARTMENT_DESC]; 

输出看起来是这样的: Moving Average for August 23rd

与上面的代码的问题是它给了我1天的一周(8月23日)的价值。 我想获得过去7天的6周移动平均线,没有写入GETDATE 49次,这将是疯狂的。

任何帮助,将不胜感激。

+0

你能告诉就像在一个模拟的Excel表格中,或者预期的输出结果是什么样子? –

回答

0

我试着创建一个简单的例子,说明你问我是否正确理解它。这使用了2周的数据,但应该适用于更大的数据集。您可以单独运行这段代码来测试和调整,如果它符合你要求的:

CREATE TABLE #calls 
(
    TotalCalls INT, 
    CallDate DATE 
); 

-- 2 weeks worth of calls 
INSERT INTO #calls 
(
    TotalCalls, 
    CallDate 
) 
VALUES 
(12, '20170801'), -- starts on a Tuesday 
(13, '20170802'), 
(17, '20170803'), 
(20, '20170804'), 
(4, '20170805'), 
(8, '20170806'), 
(10, '20170807'), 
(14, '20170808'), 
(18, '20170809'), 
(16, '20170810'), 
(7, '20170811'), 
(11, '20170812'), 
(19, '20170813'), 
(14, '20170814'); 

-- casts to numeric with decimal places for the average for accuracy 
-- DayName - gives the day names for grouping 
-- DayNo - gives you the day number for ordering 
-- Instances - gives you how many days were included in the average 
-- WHERE - filters to dates >= date - 42 for 6 weeks 
SELECT AVG(CAST(c.TotalCalls AS NUMERIC(5,2))) AvgCalls, 
     DATENAME(dw,c.CallDate) DayName, 
     DATEPART(dw, c.CallDate) DayNo, 
     COUNT(c.CallDate) Instances 
FROM #calls AS c 
WHERE c.CallDate > GETDATE() - 42 
GROUP BY DATENAME(dw, c.CallDate), DATEPART(dw, c.CallDate) 
ORDER BY DATEPART(dw, c.CallDate) 

产地:

AvgCalls DayName DayNo Instances 
13.500000 Sunday  1  2 
12.000000 Monday  2  2 
13.000000 Tuesday 3  2 
15.500000 Wednesday 4  2 
16.500000 Thursday 5  2 
13.500000 Friday  6  2 
7.500000 Saturday 7  2 
+1

什么是简单而顺畅的解决方案。这工作完美无瑕。谢谢Tanner! –

0

这里的另一种选择......

WITH 
    cte_SixWeekCal AS (
     SELECT 
      c.WEEK_NO, 
      ROW_DATE_BEG = DATEADD(WEEK, -13 + c.WEEK_NO, CAST(GETDATE() AS DATE)), 
      ROW_DATE_END = DATEADD(WEEK, -7 + c.WEEK_NO, CAST(GETDATE() AS DATE)) 
     FROM 
      (VALUES (1), (2), (3), (4), (5), (6)) c (WEEK_NO) 
     ) 
SELECT 
    swc.WEEK_NO, 
    ROW_DATE = ROW_DATE_END, 
    ahid.DEPARTMENT_DESC. 
    ahid.MOVING_AVG 
FROM 
    cte_SixWeekCal swc 
    CROSS APPLY (
       SELECT 
        ahi.DEPARTMENT_DESC, 
        MOVING_AVG = AVG(ahi.CALLS_OFFERED_ACTUALS) 
       FROM 
        [GEMDB].dbo.V_PRD_ACT_HSPLIT_intradayLCWcallsTable ahi 
       WHERE 
        ih.InvoiceDate >= swc.ROW_DATE_BEG 
        AND ih.InvoiceDate <= swc.ROW_DATE_END 
       GROUP BY 
        ahi.DEPARTMENT_DESC 
       ) ahid;