按人、日期划分的 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;

相关的子查询可能很慢。确保将repcyc_date 编入索引,以减少这个痛苦。

【讨论】:

宾果游戏。那工作得很好。我没有考虑在 WHERE 语句中明确设置代表相关性。我的思绪完全走在一条聚合路线上。非常感谢你的帮助。希望这对其他人也有帮助。 另外,同意非聚合字段的索引。好在数据并没有太大,所以运行的比较快。 好的,很好。一旦你向我们展示了 SQL,我可以看到你与那个相关的子查询很接近,但只需要将平均值限制为 rep。感谢您展示 SQL!

以上是关于按人、日期划分的 12 个月移动平均线的主要内容,如果未能解决你的问题,请参考以下文章

在python中计算指数移动平均线

过去 30 天的移动平均线

移动平均线计算不正确

计算移动平均线 MySQL?

使用核心数据聚合每日平均值,移动平均线

MACD指标