按人、日期划分的 12 个月移动平均线
Posted
技术标签:
【中文标题】按人、日期划分的 12 个月移动平均线【英文标题】:12 month moving average by person, date 【发布时间】:2013-10-10 14:47:24 【问题描述】:我有一个表 [production],其中包含以下结构:
rep (char(10))
,cyc_date (datetime) ---- already standardized to mm/01/yyyy
,amt (decimal)
我有从 2011 年 1 月 1 日到 2013 年 8 月 1 日期间每个代表的数据。我想要做的是为每个代表创建一个从 2012 年 1 月 1 日开始的 12 个月移动平均线,如下所示:
rep cyc_dt 12moAvg
-------------------------
A 1/1/2012 10000.01
A 2/1/2012 13510.05
. ........ ........
A 8/1/2013 22101.32
B 1/1/2012 98328.22
B ........ ........
其中每一行代表所述代表在规定时间的 12 个月移动平均值。我发现了一些模糊不清的例子,但我尝试了它们无济于事。似乎通过 rep 组件添加 group 是与其他示例的主要区别。
据我所知:
SELECT
rep,
cyc_date,
(
SELECT Avg([amt])
FROM production Q
WHERE Q.[cyc_date] BETWEEN DateAdd("yyyy",-1,[cyc_date]+1) AND [cyc_date]
) AS 12moavg
FROM production
该查询似乎提取了总体平均值或总和,因为相关子查询中没有分组。当我尝试分组时,我收到一个错误,它最多只能返回一行。
【问题讨论】:
cyc_dt
中的值是否总是每月的第一天?
是的,抱歉,不清楚。每个 cyc_dt 的日期标准化为每月 1 日。
谢谢。那么对于 rep
A 和 cyc_dt
2012 年 1 月 1 日,12moAvg
是否代表从 2011 年 1 月 1 日到 2011 年 12 月 1 日的 amt
值的平均值,或者您是否还包括 amt
值2012 年 1 月 1 日的平均值?
我想让它成为一个真正的 12 个月期间,包括当前期间,我会说 2012 年 1 月 1 日的值应该包括 2011 年 2 月 1 日到 2012 年 1 月 1 日的数据,包括端点。
有道理,谢谢。现在你熟悉哪些:DateAdd()
;相关子查询; DAvg()
?
【参考方案1】:
我认为它可以对相关子查询进行 2 次调整。
-
在
DateAdd()
表达式中减去 11 个月。
包含另一个 WHERE
条件以将平均值限制为与父(包含)查询的当前行相同的 rep
。
SELECT
p.rep,
p.cyc_date,
(
SELECT Avg(Q.amt)
FROM production AS Q
WHERE
Q.rep = p.rep
AND
Q.cyc_date BETWEEN DateAdd("m", -11, p.cyc_date)
AND p.cyc_date
) AS [12moavg]
FROM production AS p;
相关的子查询可能很慢。确保将rep
和cyc_date
编入索引,以减少这个痛苦。
【讨论】:
宾果游戏。那工作得很好。我没有考虑在 WHERE 语句中明确设置代表相关性。我的思绪完全走在一条聚合路线上。非常感谢你的帮助。希望这对其他人也有帮助。 另外,同意非聚合字段的索引。好在数据并没有太大,所以运行的比较快。 好的,很好。一旦你向我们展示了 SQL,我可以看到你与那个相关的子查询很接近,但只需要将平均值限制为rep
。感谢您展示 SQL!以上是关于按人、日期划分的 12 个月移动平均线的主要内容,如果未能解决你的问题,请参考以下文章