gpt4 book ai didi

mysql - 更新mysql中的余额

转载 作者:行者123 更新时间:2023-12-04 04:12:09 24 4
gpt4 key购买 nike

我有一个包含 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 与 ID 的顺序相同时,它工作得很好。但是当先有大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;

最佳答案

变量和排序在一起很棘手。如果先在子查询中排序,然后再计算变量,会不会更好?

UPDATE operation o
INNER JOIN (
SELECT
o1.id,
@balance := @balance + IFNULL(o1.credit, 0) - IFNULL(o1.debit, 0) AS balance
FROM (
SELECT id, credit, debit
FROM Operation
WHERE bankAccount_id = 1
ORDER BY valueDate ASC, id ASC
) o1
CROSS JOIN (SELECT @Balance := 0) AS v
) s ON o.id = s.id
SET o.balance = s.balance;

请注意,如果您运行的是 MySQL 8.0,则使用窗口函数可以简单得多:

UPDATE operation o
INNER JOIN (
SELECT
id,
SUM(IFNULL(o1.credit, 0) - IFNULL(o1.debit, 0))
OVER(ORDER BY valueDate, id) balance
FROM Operation
WHERE bankAccount_id = 1
) s ON o.id = s.id
SET o.balance = s.balance;

关于mysql - 更新mysql中的余额,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61528728/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com