在mysql

时间:2017-01-27 11:00:06

标签: mysql sql average

我有如下表格

id   timestamp  speed
1    11:00:01   100
2    11:05:01   110
3    11:10:01   90
4    11:15 :01  80

我需要计算下面的移动平均值

id   timestamp  speed average
1    11:00:01   100   100 
2    11:05:01   110   105
3    11:10:01   90    100
4    11:15:01   80    95

我尝试了什么

SELECT 
*,
(select avg(speed) from tbl t where tbl.timestamp<=t.timestamp) as avg
FROM 
tbl

起初它看起来很容易,但当桌子上的数据膨胀时,它太慢了

任何更快的方法?

4 个答案:

答案 0 :(得分:4)

您的查询是实现平均运行的一种方法:

SELECT t.*,
       (select avg(speed) from tbl tt where tt.timestamp <= t.timestamp) as avg
FROM tbl t;

另一种方法是使用变量:

select t.*, (sum_speed / cnt) as running_avg_speed
from (select t.*, (@rn := @rn + 1) as cnt, (@s := @s + speed) as sum_speed
      from tbl t cross join
           (select @rn := 0, @s := 0) params
      order by timestamp
     ) t;

tbl(timestamp)上的索引应进一步提高效果。

答案 1 :(得分:0)

MySQL是否支持窗口函数?

select
  id, timestamp, speed,
  avg (speed) over (order by timestamp) as average
from tbl

如果它不起作用,虽然我怀疑它是否有效:

select
  min (t1.id) as id, t1.timestamp, min (t1.speed) as speed,
  avg (t2.speed)
from
  tbl t1
  join tbl t2 on
    t2.id <= t1.id
group by
  t1.timestamp
order by
  t1.timestamp

答案 2 :(得分:0)

或者在GL的两个答案之间整齐地划分(无论如何都是表现)......

SELECT x.*, AVG(y.speed) avg
  FROM my_table x
  JOIN my_table y
    ON y.id <= x.id
 GROUP 
    BY x.id;

答案 3 :(得分:0)

简单的并发解决方案怎么样?

SET @summ=0; SET @counter=0;SELECT *,(@counter := @counter +1) as cnt, (@summ := @summ+speed) as spd, (@summ/@counter) AS avg FROM tbl;