mysql - 更新查询取决于前一行的值

标签 mysql sql moving-average

我正在尝试使用 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/

相关文章:

asp.net - 如何实现跨数据库外键约束?

mysql - 基于多个表的排名

Mysql嵌套选择与多个连接条件连接表

mysql - 从 MAX mysql 关键字获取多条记录?

algorithm - 计算时间加权移动平均值

geopandas - 如何使用 geopandas 最近邻居来制作移动平均值?

postgresql - 有没有一种简单的方法可以在 PostgreSQL 中计算 12 个月的移动平均值?

C# 到 MySQL 服务器的 SSH 隧道

sql - 如何将日期/时间安排为上午输入/输出和下午输入/输出

来自两个表的 SQL Multiple COUNT(),在一个 LEFT JOIN 中