一周中同一天的 6 周移动平均线
6 weeks Moving Average Over Same Day of week
我正在计算呼叫中心呼叫量的一周中同一天的 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 周移动平均线,而不用写 49 次 GETDATE,这太疯狂了。
如有任何帮助,我们将不胜感激。
如果我理解正确,我已经尝试创建一个简化的示例来说明您的问题。这使用了 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
还有一个选择...
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;
我正在计算呼叫中心呼叫量的一周中同一天的 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 周移动平均线,而不用写 49 次 GETDATE,这太疯狂了。
如有任何帮助,我们将不胜感激。
如果我理解正确,我已经尝试创建一个简化的示例来说明您的问题。这使用了 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
还有一个选择...
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;