我看到这里的一些人有类似我现在遇到的问题......但没有任何帮助我:/
我有一个表有2列的测试。日期和整数值。 我需要平均每N个记录。 例如
Date | Info
2013-01-01 | 210
2013-01-02 | 213
2013-01-03 | 214
2013-01-05 | 197
2013-01-06 | 192
...
让我们说N = 3
我需要使用
填充表格Averages
212.3333 (that's the average of the 3 first Info's) (210+213+214)/3
208.0000 (213+214+197)/3
201.0000 (214+197+192)/3
我试过这个
delimiter $$
DROP PROCEDURE IF EXISTS calcAvg$$
CREATE PROCEDURE calcAvg()
begin
DECLARE v_finished INTEGER DEFAULT 0;
declare v_avg DECIMAL default 0.0;
DECLARE initial_date date;
DEClARE cr CURSOR FOR
select avg(i) from (
select t.info i
from test t
where date >= initial_date
limit 3
)as s;
-- declare NOT FOUND handler
DECLARE CONTINUE HANDLER FOR NOT FOUND SET v_finished = 1;
set initial_date = '2013-01-01';
get_avg: LOOP
OPEN cr;
cr_loop: LOOP
FETCH cr INTO v_avg;
IF v_finished = 1 THEN
LEAVE cr_loop;
END IF;
insert into result values (v_avg);
END LOOP cr_loop;
CLOSE cr;
#I've to change this line... the table does not have all days
set v_dt_ini = date_add(v_dt_ini,interval 1 DAY);
#But the problem it's not the line yet...
set v_finished = 0;
if v_dt_ini > '2013-05-30' then
leave get_avg;
end if;
END LOOP get_avg;
end$$
在代码上我将N修正为3 问题在于,当我调用程序时...它会计算3条记录的第一个平均值...并且当再次执行光标时...它返回相同的值... 3个第一个记录......并且它不是我需要什么...
光标不会改变结果:/
答案 0 :(得分:3)
SELECT date,info,(select avg(info) from
(select date,info,@row1:=@row1+1 as row
from test,(SELECT @row1:=0)r
order by date desc
)wrn1
where wrn1.row between wrn2.start and wrn2.end)as avg,
start,end
FROM
(select date,info,@row:=@row+1 as row,(@row - 2) as start,@row as end
from test,(SELECT @row:=0)r
order by date desc
)wrn2
WHERE start > 0
ORDER BY date asc
这将返回
DATE INFO AVG START END
January, 01 2013 00:00:00+0000 210 212.3333 3 5
January, 02 2013 00:00:00+0000 213 208 2 4
January, 03 2013 00:00:00+0000 214 201 1 3
答案 1 :(得分:1)
您可以为此使用相关子查询。如果您想要最多n
天,包括当前日期和之后的日期,那么这将有效:
select date, info,
(select avg(t2.info)
from test t2
where datediff(t.date, t2.date) < n and
t2.date >= t.date
) as avginfo
from test t;
如果你想要n
个记录,包括当前的记录,那么下面的想法就可以了:
select date, info,
(select avg(info)
from (select t2.*
from test t2
where t2.date >= t.date
order by t2.date
limit n
) t3
) as avginfo
from test t;
但是,这会在MySQL中生成错误,我不确定如何解决它(双嵌套查询无法再识别与外部查询的相关性)。以下版本的工作方式如here所示:
select t.date, t.info, avg(t3.info)
from (select date, info,
(select t2.date
from test t2
where t2.date >= t.date
order by t2.date
limit 1 offset 2
) as date3
from test t
) t left outer join
test t3
on t3.date between t.date and t.date3
group by t.date, t.info;
答案 2 :(得分:0)
回应关于被命令的评论 - 诀窍是排序:
新值:在原始表上使用触发器 - AFTER INSERT
触发器需要选择最后N个值的平均值(SELECT AVG(valuecolumn) FROM table WHERE datecolumn <= NEW.datecolumn ORDER BY datecolumn DESC LIMIT N
)并将其插入到averages表中。
现有值:从前到后运行此选项并使用SELECT AVG(valuecolumn) FROM table WHERE datecolumn <= NEW.datecolumn ORDER BY datecolumn ASC LIMIT M,N
,其中M来自0..count-2