我需要在表中实现一个运行总和。这通常由代码完成,但我需要更新现有数据。在搜索网络后,我知道MySQL不允许更新,其中值来自同一个表中的子查询,但我也看到了克服此限制的技巧。不幸的是,我见过的一切都不符合我的需求。所以这就是最终的表格:
ID amount asum
------------------
1 10.00 10.00
2 20.00 30.00
3 -5.00 25.00
4 100.00 125.00
....
ID
列是自动增量,因此这些值是按顺序排列的。 amount
中的值来自UI,并且需要按asum
的顺序计算colunm ID
。因此,我手动更新了第一行并尝试了类似
UPDATE atable t
SET t.asum = t.amount + (SELECT s.asum FROM atable s WHERE s.ID = t.ID - 1)
WHERE t.ID > 1;
或者,列asum
是ID
< =当前ID
的所有金额的总和,所以我尝试了
UPDATE atable t
SET t.asum = (SELECT SUM(s.amount) FROM atable s WHERE s.ID <= t.ID);
这两个语句都会抛出错误1093.那里的任何人都有解决方案吗?
答案 0 :(得分:3)
尝试此查询:
-- query wanted
UPDATE atable t CROSS JOIN (SELECT @s := 0) param
SET t.asum = (@s := (@s + t.amount));
以下是一个完整的演示。
-- data
create table atable(ID int auto_increment primary key,
amount decimal(6,2), asum decimal(6,2) default 0.0);
insert into atable(amount) values
(10.00),(20.00),(-5.00),(100.00);
select * from atable;
-- query wanted
UPDATE atable t CROSS JOIN (SELECT @s := 0) param
SET t.asum = (@s := (@s + t.amount));
mysql> select * from atable;
+----+--------+------+
| ID | amount | asum |
+----+--------+------+
| 1 | 10.00 | 0.00 |
| 2 | 20.00 | 0.00 |
| 3 | -5.00 | 0.00 |
| 4 | 100.00 | 0.00 |
+----+--------+------+
4 rows in set (0.00 sec)
mysql>
mysql> -- query wanted
mysql> UPDATE atable t CROSS JOIN (SELECT @s := 0) param
-> SET t.asum = (@s := (@s + t.amount));
Query OK, 4 rows affected (0.00 sec)
Rows matched: 4 Changed: 4 Warnings: 0
mysql>
mysql> select * from atable;
+----+--------+--------+
| ID | amount | asum |
+----+--------+--------+
| 1 | 10.00 | 10.00 |
| 2 | 20.00 | 30.00 |
| 3 | -5.00 | 25.00 |
| 4 | 100.00 | 125.00 |
+----+--------+--------+
4 rows in set (0.00 sec)
答案 1 :(得分:0)
当我在脚本环境(例如MySQL Workbench)中执行查询时,它工作正常。但是,当我尝试从代码中运行它时,我收到一个错误,因为MySQL .NET连接器将@s
解释为没有值的参数。
要解决此问题,程序需要连接到连接字符串中具有指令Allow User Variables = True
的MySQL DB服务器。