使用MYSQL中的闭市价格的简单移动平均值计算和更新表格

gcu*_*bed 5 mysql sql finance average

我可以使用一些帮助(最好是一个虚拟指南)来更新下表:

CREATE TABLE `SYMBOL` (
  `day` date NOT NULL,
  `open` decimal(8,3) DEFAULT NULL,
  `high` decimal(8,3) DEFAULT NULL,
  `low` decimal(8,3) DEFAULT NULL,
  `close` decimal(8,3) DEFAULT NULL,
  `volume` bigint(20) DEFAULT NULL,
  `adj_close` decimal(8,3) DEFAULT NULL,
  `moving_average` decimal(8,3) DEFAULT NULL,
  PRIMARY KEY (`day`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Run Code Online (Sandbox Code Playgroud)

moving_average列现在为空.填充所有其他列(暂时,我很好,这是"静态",它不需要更新,因为我添加行 - 但如果这很容易做,那将是伟大的).这是我希望计算的20天移动平均线.

我尝试过尽最大努力执行这里的步骤:

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

我的查询是这样的:

SELECT
     `close`,
     (
     SELECT
          AVG(`close`) AS moving_average
     FROM
          SYMBOL T2
     WHERE
          (
               SELECT
                    COUNT(*)
               FROM
                    SYMBOL T3
               WHERE
                    `day` BETWEEN T2.day AND T1.day
          ) BETWEEN 1 AND 20
     )
FROM
     SYMBOL T1
Run Code Online (Sandbox Code Playgroud)

我是否正确修改了查询?将结果写入moving_average列需要做什么?

当我运行上面的操作时,没有任何反应(它说它运行,没有错误,让它运行很长一段时间我就停止它).列moving_average仍然具有NULL值.

我也看了这个答案: 如何计算MySQL中的多个移动平均线

但是,我不确定我需要更改为我的表的回复.

任何帮助表示赞赏.

Bar*_*nka 2

有两种方法可以做到这一点:

  1. 创建一个update更新表中每一行的查询
  2. 创建一个执行该工作的存储过程

我个人更喜欢方案2:

delimiter $$
create procedure movingAvg()
begin
    declare mv double;
    declare t date;
    declare done int default false;
    declare cur_t cursor for
         select distinct day from symbol
         order by day;
    declare cur_mv cursor for
         select avg(close) from symbol
         where day between date_add(t, interval -19 day) and t;
         -- Here you define the interval of your MV.
         -- If you want a 20-day MV, then the interval is between t-19 and t
    declare continue handler for not found set done=true;

    open cur_t;
    loop_day: loop
        fetch cur_t into t;
        if not done then
            open cur_mv;
            fetch cur_mv into mv;
            close cur_mv;
            update SYMBOL
                set moving_average = mv
                where day=t;
        else
            leave loop_day;
        end if;
    end loop loop_day;
    close cur_t;
end;
delimiter ;
Run Code Online (Sandbox Code Playgroud)