MYSQL移动平均线计算优先级无界限

时间:2014-05-20 00:28:02

标签: mysql sql join sql-update subquery

我有一个包含三列的表:id,A,B。我想用下面的计算填充E列。

** Cols C和D在我的表中不存在,它们是我希望创建的子查询并放入我的查询中,这将帮助我填充col E.看起来,C和D是移动平均值但是没有太多的例子可以帮助解决这个问题。

Table followers
 id    A   B      C                                  D                     E
  _    _   _      _                                  _                     _

  0    1   2  A0/(AVG(A0))  #1/1                B0/(AVG(B0))            (C0+D0)/2
  1    2   2  A1/(AVG(A1,A0)) #2/((2+1)/2)      B1/(AVG(B1,B0))         (C1+D1)/2
  2    3   2  A2/(AVG(A1,A2,A0)) #3/((3+2+1)/3) B2/(AVG(B1,B2,B0))      (C2+D2)/2

我如何为此编写查询?我相信我需要一个左外连接。

我在考虑将C列的计算设置为一个变量,将D列的计算设置为另一个变量。

因此,对于C列,这是我的方法:

update followers f left outer join
       followers f2...

不知道如何继续,因为我不知道我该怎么做

 f.id=f2.id where f2.id between f.id and f2.id+1.

我得到了一些使用此查询的帮助,但它没有用:

UPDATE 
    f,
    (
        SELECT AVG(f.A) 
        FROM (
            SELECT f.A  
            FROM f 
            WHERE f.id <= f.id
        ) as t 
    ) as temp,
    (
        SELECT AVG(f.B) 
        FROM (
            SELECT f.B  
            FROM f 
            WHERE f.id <= f.id
        ) as t2 
    ) as temp2
SET 
    f.C =((f.A/temp) + (f.B/temp2))/2;

2 个答案:

答案 0 :(得分:1)

我会使用子查询

SELECT id, A, B, C, D, (C+D)/2 E FROM (
    SELECT id, A, B,
    (A/(SELECT AVG(A) FROM table t2 WHERE t2.id <= t1.id)) C,
    (B/(SELECT AVG(B) FROM table t2 WHERE t2.id <= t1.id)) D
    FROM table t1 ) t3

此查询假定AVG(A)和AVG(B)始终> 0.如果不是这样,你需要使用CASE,这样你才能最终除以0。

使用JOIN的另一个版本,可能比使用子查询

更快
SELECT t3.id, t3.A, t3.B, 
(t3.A/t4.AVG_A) C, (t3.B/t4.AVG_B) D,
((t3.A/t4.AVG_A) + (t3.B/t4.AVG_B))/2 E
FROM table t3
JOIN (SELECT t1.id, AVG(t2.A) AVG_A, AVG(t2.B) AVG_B
FROM table t1
JOIN table t2 ON t2.id <= t1.id
GROUP BY t1.id) t4 ON t3.id = t4.id

答案 1 :(得分:0)

我会使用变量来解决这个问题。

select t.id, t.A, t.B,
       (case when (@n := @n + 1) is null then null
             when (@c := @c + a) is null then null
             else t.A / (@c / @n)
        end) as C,
       (case when (@d := @d + b) is null then null
             else t.B / (@d / @n)
        end) as D,
       (t.A / (@c / @n)) + (t.B / (@d / @n)) as E
from table t cross join
     (select @c := 0, @d := 0, @n := 1) vars
order by id;

您可以使用join将其添加到更新语句中。

update table t join
   (select t.id, t.A, t.B,
           (case when (@n := @n + 1) is null then null
                 when (@c := @c + a) is null then null
                 else t.A / (@c / @n)
            end) as C,
           (case when (@d := @d + b) is null then null
                 else t.B / (@d / @n)
            end) as D,
           (t.A / (@c / @n)) + (t.B / (@d / @n)) as E
    from table t cross join
         (select @c := 0, @d := 0, @e := 0, @n := 1) vars
    order by id
   ) newvals
   on t.id = newvals.id
set t.C = newvals.C,
    t.D = newvals.D,
    t.E = newvals.E;