【问题标题】:cumulative average in MySQLMySQL中的累积平均值
【发布时间】:2014-05-20 22:29:02
【问题描述】:

我有一个表,其 id 和值如下所示。当我们沿着行向下时,是否可以得到另一列,该值除以累积平均值?

original table : t1
    +----+----------------------+
    | id | Val                  |               
    +----+---------------------+-
    |  1 |                 NULL |  
    |  2 |                  136 |    
    |  3 |                   42 |


 table i want to get 
+----+---------------------+-----------------------------+
| id | Val                  | VAL/(AVG(VAL) )            |              
+----+---------------------+-----------------------------+
|  1 |                 NULL |                    NULL    | 
|  2 |                  136 |    136/((136+0)/2)=2.000   | 
|  3 |                   42 |  42/((42+136+0)/3)=0.708   |

这是我的查询:

SELECT  t1.id, t1.Val, Val/AVG(t1.Val) 
FROM    followers t1
JOIN    followers t2
ON      t2.id <= t1.id
group by t1.id;

但是我得到了这个:

+----+---------------------+----------------------+
| id | Val                 | VAL/(AVG(VAL) )      |
+----+---------------------+----------------------+
|  1 |                NULL |   NULL               | 
|  2 |                 136 | 1.0000               | 
|  3 |                  42 | 1.0000               |

似乎 AVG(Val) 从 col Val 返回相同的值。

我希望在这里做与此链接类似的事情,但我想要平均而不是总和。 MySQL SELECT function to sum current data


我重新实现了编辑并考虑了带有 NULL 的行:

+----+---------------------+---------------------+
| id | Val                 | VAL/(AVG(VAL) )      |
+----+---------------------+----------------------+
|  1 |                NULL |    NULL              | 
|  2 |                 136 |  1.0000              |<---need this to = 2.000 
|  3 |                  42 |  0.4719              |<---need this to = 0.708 

SELECT  t1.id, t1.Val, t1.Val/(SUM(t2.Val)/(t1.id)) AS C
FROM    followers t1
JOIN    followers t2
ON      t2.id <= t1.id
group by t1.id;

【问题讨论】:

  • 您正在计算总数。然后就是简单的数学。这是使用变量完成的。这是一个示例:stackoverflow.com/questions/664700/…stackoverflow.com/questions/8359077/…
  • 你可以试试t1.val/AVG(t2.val)
  • 为什么不在应用层计算呢?在 DB 层中执行此操作实际上是要求 DB 执行它无论如何都没有优化的逻辑。
  • @MikeBrant 你确定吗?我觉得还可以!?!
  • @Strawberry Well 将表连接到自身,相当于部分笛卡尔连接,如下面的 Gordon Linoff 的回答所建议的那样。或者使用 MySQL 变量执行其他一些基于过程的方法可能不如仅查询单个行并计算应用程序中的运行总数那么有效。

标签: mysql


【解决方案1】:

我想你想要t2.val 中的avg()

SELECT  t1.id, t1.Val, t1.Val/AVG(t2.Val) 
FROM    followers t1 JOIN
        followers t2
        ON t2.id <= t1.id
group by t1.id;

编辑:

Mike Brand 是正确的,上述方法是做你想做的事的糟糕方法。在 MySQL 中,你可以使用变量来做同样的事情:

select t.id, t.val,
       (case when (@n := @n + 1) is null then null
             when (@cumval := @cumval + val) is null then null
             else t.val / (@cumval / @n)
        end)
from followers t cross join
     (select @n := 0, @cumval := 0) vars
order by t.id;

这可能与 val 的 NULL 值不符,但它提供了一种在 MySQL 中进行计算的更快方法的想法。

【讨论】:

  • 虽然这应该可行,但在相当大的数据库表上会非常慢。您实质上将创建 n * ((n-1)/2) 行。如果您的数据库是 10 行,则很好,这会导致连接后有 45 行。但是,如果您的数据库是 1M 行,则生成的连接将接近 5000 亿行。
  • @Strawberry 。 . .谢谢你。
  • @GordonLinoff 原始查询有效。带有变量的那个为我想要的行返回 NULL。
猜你喜欢
  • 2016-07-11
  • 2012-06-19
  • 2022-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-19
相关资源
最近更新 更多