Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/87.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在MySQL中创建一个累积和列_Mysql_Sql_Cumulative Sum - Fatal编程技术网

在MySQL中创建一个累积和列

在MySQL中创建一个累积和列,mysql,sql,cumulative-sum,Mysql,Sql,Cumulative Sum,我有一张这样的桌子: id count 1 100 2 50 3 10 id count cumulative_sum 1 100 100 2 50 150 3 10 160 我想添加一个名为cumulative_sum的新列,因此该表如下所示: id count 1 100 2 50 3 10 id count cumulative_sum 1 100 100 2 50

我有一张这样的桌子:

id   count
1    100
2    50
3    10
id   count  cumulative_sum
1    100    100
2    50     150
3    10     160
我想添加一个名为cumulative_sum的新列,因此该表如下所示:

id   count
1    100
2    50
3    10
id   count  cumulative_sum
1    100    100
2    50     150
3    10     160
是否有一个MySQL更新语句可以轻松做到这一点?实现这一点的最佳方法是什么?

使用相关查询: 注:

JOIN SELECT@running_total:=0 r是一个交叉连接,允许在不需要单独的SET命令的情况下声明变量。 MySQL对于任何子查询/派生表/内联视图都需要表别名r 注意事项:

MySQL特有的;不可移植到其他数据库 订单是重要的;它可以确保顺序与OP匹配,并对更复杂的变量使用有更大的影响,例如:psuedo ROW_NUMBER/RANK功能,这是MySQL所缺乏的
您还可以创建一个触发器,在每次插入之前计算总和

delimiter |

CREATE TRIGGER calCumluativeSum  BEFORE INSERT ON someTable
  FOR EACH ROW BEGIN

  SET cumulative_sum = (
     SELECT SUM(x.count)
        FROM someTable x
        WHERE x.id <= NEW.id
    )

    set  NEW.cumulative_sum = cumulative_sum;
  END;
|

我没有测试过这个

如果性能有问题,可以使用MySQL变量:

set @csum := 0;
update YourTable
set cumulative_sum = (@csum := @csum + count)
order by id;
或者,您可以删除“累计总和”列,并在每个查询中计算它:

set @csum := 0;
select id, count, (@csum := @csum + count) as cumulative_sum
from YourTable
order by id;
这将以运行方式计算运行总和:

示例查询

SET @runtot:=0;
SELECT
   q1.d,
   q1.c,
   (@runtot := @runtot + q1.c) AS rt
FROM
   (SELECT
       DAYOFYEAR(date) AS d,
       COUNT(*) AS c
    FROM  orders
    WHERE  hasPaid > 0
    GROUP  BY d
    ORDER  BY d) AS q1

MySQL 8.0/MariaDB支持窗口化:

输出:

┌─────┬──────┬────────────────┐
│ id  │ cnt  │ cumulative_sum │
├─────┼──────┼────────────────┤
│  1  │ 100  │            100 │
│  2  │  50  │            150 │
│  3  │  10  │            160 │
└─────┴──────┴────────────────┘

从tableName中选择id、count、sumcountoverorder by count desc作为累计总和

我在count列上使用了sum aggregate函数,然后使用了over子句。它分别对每一行进行汇总。第一排刚好是100。第二行是100+50。第三行是100+50+10,以此类推。所以基本上每一行都是它和前面所有行的和,最后一行是所有行的和。所以看这一点的方法是,每一行都是ID小于或等于自身的量的总和

  select t1.id, t1.count, SUM(t2.count) cumulative_sum
    from table t1 
        join table t2 on t1.id >= t2.id
    group by t1.id, t1.count
逐步:

1-给出下表:

select *
from table t1 
order by t1.id;

id  | count
 1  |  11
 2  |  12   
 3  |  13
2-按组获取信息

select *
from table t1 
    join table t2 on t1.id >= t2.id
order by t1.id, t2.id;

id  | count | id | count
 1  | 11    | 1  |  11

 2  | 12    | 1  |  11
 2  | 12    | 2  |  12

 3  | 13    | 1  |  11
 3  | 13    | 2  |  12
 3  | 13    | 3  |  13
3-步骤3:按t1.id组对所有计数求和

select t1.id, t1.count, SUM(t2.count) cumulative_sum
from table t1 
    join table t2 on t1.id >= t2.id
group by t1.id, t1.count;


id  | count | cumulative_sum
 1  |  11   |    11
 2  |  12   |    23
 3  |  13   |    36


虽然OP确实要求更新,但这是非规范化的,可能不便于正确维护。使用交叉连接来定义变量,而不需要使用SET。我的表有3600万条记录,因此这确实有助于加快速度!请注意,按累计总和排序可能会强制进行全表扫描;有什么建议可以扩展到在一个组中进行累加吗?e、 g.按名称或类似名称分组,然后仅对具有相同名称的记录进行累计合计name@zaitsman您可以将其用作子查询;在外部查询中,按您想要的任何内容分组,然后使用MAX MySQL函数获得正确的累积摘要—为组内记录计算的上一个摘要。我会将ORDER by t.id ASC添加到主查询中,以确保它始终有效。我的第一个想法也是添加ORDER by。但这并不重要。在加法变成非关联之前,至少:@OMG Poines:我认为您需要在连接选择中使用SELECT@running_total:=0部分变量示例。对于使用相关查询,表x来自何处?除非内部发生优化,相关子查询相当于在^2时间内执行的三角形联接,不会进行缩放。请解释您的答案答案答案有效且为一行。它还可以在select开始时将变量初始化/重置为零。虽然这可能会解决问题,但最好对其进行一些解释,这样会使其他人受益:这不是一个相关子查询或相关子查询。。。相关子查询跟随选择…,选择。。。。从表2中,其中table2.id=table1.id从表1中,您拥有的是一个窗口查询..我正在使用windows函数查找累积和。谢谢。添加了一些逐步了解最终查询的内容
select *
from table t1 
order by t1.id;

id  | count
 1  |  11
 2  |  12   
 3  |  13
select *
from table t1 
    join table t2 on t1.id >= t2.id
order by t1.id, t2.id;

id  | count | id | count
 1  | 11    | 1  |  11

 2  | 12    | 1  |  11
 2  | 12    | 2  |  12

 3  | 13    | 1  |  11
 3  | 13    | 2  |  12
 3  | 13    | 3  |  13
select t1.id, t1.count, SUM(t2.count) cumulative_sum
from table t1 
    join table t2 on t1.id >= t2.id
group by t1.id, t1.count;


id  | count | cumulative_sum
 1  |  11   |    11
 2  |  12   |    23
 3  |  13   |    36