我有如下表格
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
起初它看起来很容易,但当桌子上的数据膨胀时,它太慢了
任何更快的方法?
答案 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;