SQL移动平均线

Don*_*n P 13 sql hive moving-average

如何在SQL中创建移动平均线?

当前表格:

Date             Clicks 
2012-05-01       2,230
2012-05-02       3,150
2012-05-03       5,520
2012-05-04       1,330
2012-05-05       2,260
2012-05-06       3,540
2012-05-07       2,330
Run Code Online (Sandbox Code Playgroud)

所需的表格或输出:

Date             Clicks    3 day Moving Average
2012-05-01       2,230
2012-05-02       3,150
2012-05-03       5,520          4,360
2012-05-04       1,330          3,330
2012-05-05       2,260          3,120
2012-05-06       3,540          3,320
2012-05-07       2,330          3,010
Run Code Online (Sandbox Code Playgroud)

Die*_*ggi 18

这是Evergreen Joe Celko的问题.我忽略了使用哪个DBMS平台.但无论如何,Joe能够在十多年前使用标准SQL回答这个问题.

Joe Celko SQL Puzzles and Answers引用:"最后一次更新尝试表明我们可以使用谓词来构建一个可以给出移动平均值的查询:"

SELECT S1.sample_time, AVG(S2.load) AS avg_prev_hour_load
FROM Samples AS S1, Samples AS S2
WHERE S2.sample_time
BETWEEN (S1.sample_time - INTERVAL 1 HOUR)
AND S1.sample_time
GROUP BY S1.sample_time;
Run Code Online (Sandbox Code Playgroud)

额外列或查询方法更好吗?查询在技术上更好,因为UPDATE方法将对数据库进行非规范化.但是,如果记录的历史数据不会改变并且计算移动平均值很昂贵,您可以考虑使用列方法.

MS SQL示例:

CREATE TABLE #TestDW
( Date1 datetime,
  LoadValue Numeric(13,6)
);

INSERT INTO #TestDW VALUES('2012-06-09' , '3.540' );
INSERT INTO #TestDW VALUES('2012-06-08' , '2.260' );
INSERT INTO #TestDW VALUES('2012-06-07' , '1.330' );
INSERT INTO #TestDW VALUES('2012-06-06' , '5.520' );
INSERT INTO #TestDW VALUES('2012-06-05' , '3.150' );
INSERT INTO #TestDW VALUES('2012-06-04' , '2.230' );
Run Code Online (Sandbox Code Playgroud)

SQL拼图查询:

SELECT S1.date1,  AVG(S2.LoadValue) AS avg_prev_3_days
FROM #TestDW AS S1, #TestDW AS S2
WHERE S2.date1
    BETWEEN DATEADD(d, -2, S1.date1 )
    AND S1.date1
GROUP BY S1.date1
order by 1;
Run Code Online (Sandbox Code Playgroud)


Bri*_*ter 8

一种方法是在同一个表上连接几次.

select
 (Current.Clicks 
  + isnull(P1.Clicks, 0)
  + isnull(P2.Clicks, 0)
  + isnull(P3.Clicks, 0)) / 4 as MovingAvg3
from
 MyTable as Current
 left join MyTable as P1 on P1.Date = DateAdd(day, -1, Current.Date)
 left join MyTable as P2 on P2.Date = DateAdd(day, -2, Current.Date)
 left join MyTable as P3 on P3.Date = DateAdd(day, -3, Current.Date)
Run Code Online (Sandbox Code Playgroud)

调整ON-Clauses的DateAdd组件,以匹配您是否希望移动平均线严格地从过去到现在或几天前到过去几天.

  • 这适用于只需要几个数据点的移动平均值的情况.
  • 对于具有多个数据点的移动平均线,这不是最佳解决方案.