2017-08-30 5 views
0

Je calcule la moyenne mobile de 6 semaines, pour les mêmes jours de la semaine, pour le volume d'appels dans un centre d'appels.6 semaines Moyenne mobile sur le même jour de la semaine

Ce que je veux dire par là les mêmes 6 jours précédents (derniers 6 derniers 6, Tuesdays, etc.) wednesdays

J'ai le code suivant travail, mais pas flexible du tout:

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]; 

la sortie ressemble à ceci: Moving Average for August 23rd

le problème avec le code ci-dessus est-il me donne la valeur pour 1 jour de la semaine (Août 23ème). Je voudrais obtenir la moyenne mobile de 6 semaines pour les 7 derniers jours, sans écrire GETDATE 49 fois, ce qui serait fou.

Toute aide serait appréciée.

+0

Pouvez-vous montrer comme dans une feuille Excel maquette ou quelque chose à quoi ressemblerait la sortie attendue? –

Répondre

0

J'ai essayé de créer un exemple simplifié de ce que vous demandez si je l'ai bien compris. Cela utilise 2 semaines de données mais devrait fonctionner pour des ensembles de données plus volumineux. Vous pouvez exécuter ce code dans l'isolement pour tester et adapter si elle correspond à vos besoins:

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) 

Produit:

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

Quelle solution simple et lisse. Cela fonctionne parfaitement. Merci Tanner! –

0

est ici une autre option ...

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;