2014-10-09 86 views
0

的平均我有这样的事情:一个MySQL查询得到,每每一行,前面的三排

id  | value 
--------------- 
201311 | 10 
201312 | 15 
201401 | 20 
201402 | 5 
201403 | 17 

,我需要这样一个结果:

201311 | NULL or 0 
201312 | 3.3  // 10/3 
201401 | 8.3  // (15+10)/3 
201402 | 15  // (20+15+10)/3 
201403 | 13.3 // (5+20+15)/3 

到目前为止,我得到了我可以得到最后三个以前的行的AVG像这样的点:

select AVG(c.value) FROM (select b.value from table as b where b.id < 201401 order by b.id DESC LIMIT 3) as c 

手动传递ID。我无法为每个ID做到这一点。

任何想法将不胜感激!

非常感谢。

问候

+0

你想要这样的结果,但为什么你的where子句湾ID <201401.请提供有效的结果。 NULL或0从哪里来? 201311得到价值10即使你平均它不会使它0 – 2014-10-09 09:21:35

+0

我把201401,因为我无法将每个ID传递给该查询。 NULL或0是因为我需要前面3行的平均值 – Gotrekk 2014-10-09 09:26:45

+1

Er,25/2 = 12.5 – Strawberry 2014-10-09 09:38:46

回答

0

我得到这个现在:

SELECT a.id, (select AVG(b.value) FROM table as b where b.id < a.id AND str_to_date(CONCAT(b.id,'01'), '%Y%m%d') >= DATE_SUB(str_to_date(CONCAT(a.id,'01'), '%Y%m%d'), INTERVAL 3 MONTH)) FROM `table` as a WHERE 1 

但我敢肯定应该有一个更好/更简洁的方案

+0

只是试图在sql小提琴中使用相同的方法。 ROFL。但为什么你需要再次限制日期而不是LIMIT? – 2014-10-09 09:48:37

+0

显然LIMIT是要运行的最后一件事,所以在AVG计算过程中它被忽略:( – Gotrekk 2014-10-09 09:59:00

0

我认为你必须写一个存储过程,使用游标,通过该表进行迭代,并使用您的游标循环中计算出的值填充的新表。如果你在编写光标循环时需要帮助,只需放下一条评论,我可以给你一个例子。

+0

不,谢谢,我真的需要通过查询来解决它 – Gotrekk 2014-10-09 09:30:09

+0

作为就我的理解而言,SELECT查询本质上是一个批处理过程,而您想要的信息需要按特定顺序在表上进行迭代,因此需要使用游标。 – raymondboswel 2014-10-09 12:43:12

0
select a.id,coalesce(b.value,0) from test a left outer join 
(select a.id, sum(b.value)/3 as value from 
(select @row:[email protected]+1 as rownum,id,value from test,(select @row:=0)r) a, 
(select @row1:[email protected]+1 as rownum,id,value from test,(select @row1:=0)r) b 
where b.rownum in (a.rownum-1,a.rownum-2,a.rownum-3) 
group by a.rownum) b 
on a.id=b.id;