我需要做类似的事情:
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扩展。
答案 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)
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可以有效地解决这个问题。