如何使用MySQL计算移动平均线?

时间:2009-05-18 16:02:42

标签: sql mysql statistics

我需要做类似的事情:

SELECT value_column1 
FROM table1 
WHERE datetime_column1 >= '2009-01-01 00:00:00' 
ORDER BY datetime_column1;

除了value_column1之外,我还需要检索value_column1之前20个值的moving average

首选标准SQL,但如果需要,我将使用MySQL扩展。

6 个答案:

答案 0 :(得分:18)

这只是我的头顶,我正在出门,所以它没有经过测试。我也无法想象它在任何类型的大型数据集上都能表现得很好。我确实确认它至少在没有错误的情况下运行。 :)

SELECT
     value_column1,
     (
     SELECT
          AVG(value_column1) AS moving_average
     FROM
          Table1 T2
     WHERE
          (
               SELECT
                    COUNT(*)
               FROM
                    Table1 T3
               WHERE
                    date_column1 BETWEEN T2.date_column1 AND T1.date_column1
          ) BETWEEN 1 AND 20
     )
FROM
     Table1 T1

答案 1 :(得分:2)

汤姆H的方法会奏效。如果您有一个标识列,可以像这样简化它:

SELECT T1.id, T1.value_column1, avg(T2.value_column1)
FROM table1 T1
INNER JOIN table1 T2 ON T2.Id BETWEEN T1.Id-19 AND T1.Id

答案 2 :(得分:1)

当我遇到类似的问题时,由于各种原因,我最终使用临时表,但这使得这更容易!就模式而言,我所做的看起来与你正在做的非常相似。

使模式类似于ID identity,start_date,end_date,value。选择时,根据身份ID执行前20个的子选择平均值。

只有在您发现自己已经因为其他原因而使用临时表时才这样做(我为不同的指标反复点击相同的行,因此使用小数据集会很有帮助。)

答案 3 :(得分:1)

我的解决方案在表格中添加了一个行号。以下示例代码可能有所帮助:

set @MA_period=5;
select id1,tmp1.date_time,tmp1.c,avg(tmp2.c) from 
(select @b:=@b+1 as id1,date_time,c from websource.EURUSD,(select @b:=0) bb order by date_time asc) tmp1,
(select @a:=@a+1 as id2,date_time,c from websource.EURUSD,(select @a:=0) aa order by date_time asc) tmp2
where id1>@MA_period and id1>=id2 and id2>(id1-@MA_period)
group by id1
order by id1 asc,id2 asc

答案 4 :(得分:1)

我意识到这个答案已经晚了7年。我有类似的要求,并认为我会分享我的解决方案,以防它对其他人有用。

有一些用于技术分析的MySQL扩展包括一个简单的移动平均线。它们非常易于安装和使用:https://github.com/mysqludf/lib_mysqludf_ta#readme

一旦安装了UDF(根据README中的说明),您可以在select语句中包含一个简单的移动平均值,如下所示:

SELECT TA_SMA(value_column1, 20) AS sma_20 FROM table1 ORDER BY datetime_column1 

答案 5 :(得分:0)

根据我的经验,从5.5.x开始,Mysql不会在依赖选择上使用索引,无论是子查询还是连接。这会对性能产生非常显着的影响,其中依赖选择标准在每一行上都会发生变化。

移动平均线是属于此类别的查询示例。执行时间可能会随着行的平方而增加。为了避免这种情况,选择了一个数据库引擎,可以对依赖选择执行索引查找。我发现postgres可以有效地解决这个问题。