我正在尝试使用 MySQL 的 SQL 查询来计算 200 行的指数移动平均线 (EMA)。每行都取决于前一行的值。公式为:
EMA = ((price - EMA(previous_average)) * (2 / (200 + 1))) + EMA(previous_average)
我的 table 最初看起来像
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
我的 table 看起来像
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 查询?
最佳答案
试试这个
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 的行的价格列中获取第一个平均值。
关于mysql - 更新查询取决于前一行的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15165041/