【发布时间】:2020-08-15 03:08:41
【问题描述】:
我有一个包含 5 列的 Operation 表:
- 身份证
- bankAccount_id
- 值日期
- 借记(始终为正)
- 学分
- 余额
我想更新一个银行账户所有操作的余额。
在阅读了一些 SO 问题和答案后,我最终得到了这个 SQL 请求:
UPDATE Operation INNER JOIN (
SELECT
id,
credit,
debit,
@Balance := @Balance + IFNULL(credit,0) - IFNULL(debit,0) AS Balance
FROM Operation, (SELECT @Balance := 0) AS variableInit
WHERE bankAccount_id = 1
ORDER BY valueDate ASC, id ASC
) subRequest ON Operation.id = subRequest.id
SET Operation.balance = subRequest.Balance;
当操作的 valueDates 与 IDs 的顺序相同时,它会很好地工作。但是当先有大ID的操作时,就不行了。
如您所见,操作 22 是最后更新的,尽管它是按起息日排序的第一个!
+----+---------------------+--------+---------+---------+
| id | valueDate | debit | credit | balance |
+----+---------------------+--------+---------+---------+
| 22 | 2018-01-01 00:00:00 | NULL | 103.00 | 618.00 |
| 1 | 2020-01-15 14:00:00 | NULL | 1000.00 | 1000.00 |
| 2 | 2020-01-15 15:00:00 | NULL | 200.00 | 1200.00 |
| 3 | 2020-01-15 16:00:00 | 50.00 | NULL | 1150.00 |
| 4 | 2020-01-18 17:00:00 | 200.00 | NULL | 950.00 |
| 5 | 2020-01-19 18:00:00 | NULL | 20.00 | 970.00 |
| 6 | 2020-01-21 20:00:00 | 500.00 | NULL | 470.00 |
| 7 | 2020-01-21 20:00:00 | 10.00 | NULL | 460.00 |
| 8 | 2020-01-21 20:00:00 | NULL | 30.00 | 490.00 |
| 9 | 2020-02-02 01:00:00 | 5.00 | NULL | 485.00 |
| 10 | 2020-02-10 09:00:00 | 10.00 | NULL | 475.00 |
| 11 | 2020-02-11 10:00:00 | NULL | 40.00 | 515.00 |
+----+---------------------+--------+---------+---------+
我不明白的是,当我单独运行内部查询时,它会以正确的顺序和正确的平衡返回操作!
如何使更新查询正常工作?
这是您可以用于测试的数据结构:
CREATE TABLE `Operation` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`valueDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`debit` decimal(10,2) DEFAULT NULL,
`credit` decimal(10,2) DEFAULT NULL,
`balance` decimal(10,2) NOT NULL,
`bankAccount_id` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `Operation` VALUES (1,'2020-01-15 13:00:00',NULL,1000.00,0.00,1),(2,'2020-01-15 14:00:00',NULL,200.00,0.00,1),(3,'2020-01-15 15:00:00',50.00,NULL,0.00,1),(4,'2020-01-18 16:00:00',200.00,NULL,0.00,1),(5,'2020-01-19 17:00:00',NULL,20.00,0.00,1),(6,'2020-01-21 19:00:00',500.00,NULL,0.00,1),(7,'2020-01-21 19:00:00',10.00,NULL,0.00,1),(8,'2020-01-21 19:00:00',NULL,30.00,0.00,1),(9,'2020-02-02 00:00:00',5.00,NULL,0.00,1),(10,'2020-02-10 08:00:00',10.00,NULL,0.00,1),(11,'2020-02-11 09:00:00',NULL,40.00,0.00,1),(12,'2020-01-21 19:00:00',NULL,500.00,0.00,2),(13,'2020-01-22 20:00:00',NULL,15.00,0.00,2),(14,'2020-02-02 00:00:00',NULL,5.00,0.00,2),(15,'2020-02-05 03:00:00',30.00,NULL,0.00,2),(16,'2020-02-10 08:00:00',NULL,60.00,0.00,2),(17,'2019-12-30 22:00:00',NULL,50.00,0.00,3),(18,'2020-01-21 19:00:00',10.00,NULL,0.00,3),(19,'2020-01-21 19:00:00',30.00,NULL,0.00,3),(20,'2020-01-21 19:00:00',100.00,NULL,0.00,3),(21,'2020-01-27 22:00:00',NULL,55.00,0.00,3),(22,'2017-12-31 23:00:00',NULL,103.00,0.00,1);
您可以通过以下方式订购操作:
select * from Operation where bankAccount_id = 1 ORDER BY valueDate ASC, id ASC;
【问题讨论】:
-
你能告诉我们预期的输出吗?
-
我认为您向我们展示了输出。你能展示一些样本输入吗?而且,您使用什么版本的 MySQL?请edit您的问题。
标签: mysql sql database join sql-update