2014-01-11 36 views
1

我正在寻找在MySQL表中创建一列,以计算另一列的最后五个值的运行方差(或标准偏差,以最容易的为准)。我目前使用三个变量来订购数据:ID,日期和计数器(每个ID日期配对计数器从1开始上升)。所以每次新的ID-date组合开始时,我都希望这个新的差异列也重置。这里是我要去的一点点样本:在MySQL中创建运行差异列

 
+----+--------+---------+-------+--------------------------+ 
| ID | date | counter | value |  var(value)  | 
+----+--------+---------+-------+--------------------------+ 
| 11 | 1/1/13 |  1 | 2.1 | var(2.1)     | 
| 11 | 1/1/13 |  2 | 2.4 | var(2.1,2.4)    | 
| 11 | 1/1/13 |  3 | 2.3 | var(2.1,2.4,2.3)   | 
| 11 | 1/1/13 |  4 | 2.5 | var(2.1,2.4,2.3,2.5)  | 
| 11 | 1/1/13 |  5 | 2.3 | var(2.1,2.4,2.3,2.5,2.3) | 
| 11 | 1/1/13 |  6 | 2.5 | var(2.4,2.3,2.5,2.3,2.5) | 
| 11 | 1/3/13 |  1 | 5.4 | var(5.4)     | 
| 11 | 1/3/13 |  2 | 4.3 | var(5.4,4.3)    | 
| 11 | 1/3/13 |  3 | 3.4 | var(5.4,4.3,3.4)   | 
| 11 | 1/3/13 |  4 | 2.1 | var(5.4,4.3,3.4,2.1)  | 
+----+--------+---------+-------+--------------------------+ 

有没有人知道这是如何在MySQL中完成的?我还没有找到解决任何类似这个问题的问题。

非常感谢!

+0

它可以完成,但它有点工作。让我们先看看你的一些努力 - 展示一个尝试。这不是一个编码服务。 – Bohemian

+0

或者我们只是给你答案 – Strawberry

回答

0

方差是每个值与平均值之差的平方和的平均值。所以,你可以做很多连接和算术。事情是这样的:使用适当的聚合功能,如VARIANCE()

select t.*, 
     (case when t1.date is null then 0 
      when t2.date is null 
      then (pow(t.value - (t.value + t1.value)/2, 2) + 
        pow(t1.value - (t.value + t1.value)/2, 2))/2 
      when t3.date is null 
      then (pow(t.value - (t.value + t1.value + t2.value)/3, 2) + 
        pow(t1.value - (t.value + t1.value + t2.value)/3, 2) + 
        pow(t2.value - (t.value + t1.value + t2.value)/3, 2) 
       )/3 
      when t4.date is null 
      then (pow(t.value - (t.value + t1.value + t2.value + t3.value)/4, 2) + 
        pow(t1.value - (t.value + t1.value + t2.value + t3.value)/4, 2) + 
        pow(t2.value - (t.value + t1.value + t2.value + t3.value)/4, 2) + 
        pow(t3.value - (t.value + t1.value + t2.value + t3.value)/4, 2) 
       )/4 
      else (pow(t.value - (t.value + t1.value + t2.value + t3.value + t4.value)/5, 2) + 
        pow(t1.value - (t.value + t1.value + t2.value + t3.value + t4.value)/5, 2) + 
        pow(t2.value - (t.value + t1.value + t2.value + t3.value + t4.value)/5, 2) + 
        pow(t3.value - (t.value + t1.value + t2.value + t3.value + t4.value)/5, 2) + 
        pow(t4.value - (t.value + t1.value + t2.value + t3.value + t4.value)/5, 2) 
       )/5 
     end) as var 
from t left outer join 
    t t1 
    on t.date = t1.date and t.counter = t1.counter + 1 left outer join 
    t t2 
    on t.date = t2.date and t.counter = t2.counter + 2 left outer join 
    t t3 
    on t.date = t3.date and t.counter = t3.counter + 3 left outer join 
    t t4 
    on t.date = t4.date and t.counter = t4.counter + 4; 
+0

哇。真?我错过了什么吗? :/ – eggyal

2

您可以自联接:

SELECT a.*, VARIANCE(b.value) 
FROM  my_table a 
    JOIN my_table b ON b.ID  = a.ID 
        AND b.date  = a.date 
        AND b.counter <= a.counter 
GROUP BY a.ID, a.date, a.counter, a.value 

看到它的sqlfiddle

+0

+1不错。在 – Bohemian

+0

+1第一次看到这个功能之前还没碰到过这个agg功能。 –