如果数据集中存在间隙,则使用mysql计算移动平均值会导致问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如果数据集中存在间隙,则使用mysql计算移动平均值会导致问题相关的知识,希望对你有一定的参考价值。

我的问题是我尝试从我的表中计算一些移动平均值(每行一个平均值)。它实际上有效,但如果涉及到诸如id [20,18,17]或日期[2018-05-11,2018-05-9,2018-05-8]之类的间隙,则计算会出错。我正在寻找一种方法来使用特定数量的下一行来防止这种情况发生。

该表包含id (auto_increment), date and close (Float)

这是我的代码:

CREATE DEFINER=`root`@`localhost` PROCEDURE `moving_avg`(IN periode INT)
    NO SQL
BEGIN
    select hist_ask.id, hist_ask.date, hist_ask.close, round(avg(past.close),2) as mavg   
    from hist_ask    
    join hist_ask as past     
      on past.id between hist_ask.id - (periode-1)  and hist_ask.id
    group by hist_ask.id, hist_ask.close 
    ORDER BY hist_ask.id DESC 
    LIMIT 10;
END

我使用的表看起来像这样

id , date       , close
20 , 2018-10-13 , 12086.5
19 , 2018-10-12 , 12002.2
17 , 2018-10-11 , 12007.0
and so on

输出如下所示:

The output I get from the query

提前致谢!

答案

我终于使用临时表使其工作。我现在可以给程序提供两个参数:

  1. periode:计算移动平均线的周期
  2. _limit:限制结果集

表现很重要的是

ALTER TABLE temp
    ENGINE=MyISAM;

声明,因为它显着减少了执行时间。例如,当处理2000行时,它需要大约0.5秒,在添加它之前需要大约6秒

这是代码:

CREATE DEFINER=`root`@`localhost` PROCEDURE `moving_avg`(IN periode INT, IN _limit INT)
    NO SQL
BEGIN

 DECLARE a FLOAT DEFAULT 0;
 DECLARE i INT DEFAULT 0;
 DECLARE count_limit INT  DEFAULT 0;

   SET @rn=0;
 CREATE TEMPORARY TABLE IF NOT EXISTS temp (
                SELECT 
                    @rn:=@rn+1 AS pri_id, 
                    date, 
                    close , a AS 
                    mavg 
                FROM hist_ask);

ALTER TABLE temp
ENGINE=MyISAM;

 SET i=(SELECT pri_id FROM temp ORDER by pri_id DESC LIMIT 1);
 SET count_limit= (i-_limit)-periode;


WHILE i>count_limit DO
SET a= (SELECT avg(close) FROM temp WHERE pri_id BETWEEN i-(periode-1) AND i);
UPDATE temp SET mavg=a WHERE pri_id=i;
SET i=i-1;
END WHILE;

SELECT pri_id,date,close,round(mavg,2) AS mavg FROM temp ORDER BY pri_id DESC LIMIT _limit;


DROP TABLE temp;

END

结果如下:

CALL `moving_avg`(3,5)
  • pri_id,日期,关闭,mavg
  • 1999 2018-09-13 12086.6 12032.03
  • 1998 2018-09-11 12002.2 11983.47
  • 1997 2018-09-10 12007.3 11976.53
  • 1996 2018-09-07 11940.9 11993.80
  • 1995 2018-09-06 11981.4 12089.23

5行返回0.047秒/0.000秒

以上是关于如果数据集中存在间隙,则使用mysql计算移动平均值会导致问题的主要内容,如果未能解决你的问题,请参考以下文章

如何在 MySQL 记录集中找到 ID 间隙?

计算移动平均线 MySQL?

移动平均线计算不正确

计算MySQL列中不同值的移动平均值

什么是间隙锁?

短期差距与平均差距