UPDATE查询取决于前一行的值

时间:2013-03-01 19:07:47

标签: mysql sql moving-average

我正在尝试使用MySQL的SQL查询来计算200行指数移动平均值(EMA)。每行取决于前一行的值。公式是:

EMA = ((price - EMA(previous_average)) * (2 / (200 + 1))) + EMA(previous_average)

我的表最初看起来像

id       price      average
---------------------------
1        29.05      29.05000000
2        29.04       0.00000000
3        29.06       0.00000000
4        29.05       0.00000000

(我手动将第一行的“平均值”设置为“价格”,以便下面的查询具有初始值)

运行此查询

UPDATE
  quotes
INNER JOIN
  quotes AS quotes_previous ON quotes_previous.id = table.id - 1
SET
  table.average = ((quotes.price - quotes_previous.average) * (2 / (200 + 1)) + quotes_previous.average)
where
  quotes.id > 1

我的表格看起来像

id       price      average
---------------------------
1        29.05      29.05000000
2        29.04      29.04990050
3        29.06       1.13937059
3        29.05       1.13927205

正如您所看到的,除前两行外,其他所有人的平均值显然都不正确。

我认为问题是查询需要按id顺序更新行。但是当我向查询添加“ORDER BY id”时,我得到“错误1221(HY000):UPDATE和ORDER BY的使用不正确。”我相信我不能在UPDATE查询中使用ORDER BY和JOIN。

那么,如何运行依赖于前一行值的UPDATE查询?

1 个答案:

答案 0 :(得分:1)

试试这个

UPDATE quotes q INNER JOIN 
(SELECT id,
       price,
       ((price - @prev) * (2 / (200 + 1))) + @prev average,
       @prev = ((price - @prev) * (2 / (200 + 1))) + @prev
  FROM quotes, (SELECT @prev := (SELECT price FROM quotes ORDER BY id LIMIT 1) i) n
 ORDER BY id) t ON q.id=t.id
   SET q.average = t.average

输出

+------+-------+-------------+
| id   | price | average     |
+------+-------+-------------+
|    1 | 29.05 | 29.05000000 |
|    2 | 29.04 | 29.04990050 |
|    3 | 29.06 | 29.05009950 |
|    4 | 29.05 | 29.05000000 |
+------+-------+-------------+

重新运行是安全的,因为它从id值最低的行的价格列中获取第一个平均值。