在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