更新MySQL中目标行的下一行

时间:2013-10-04 01:21:17

标签: mysql

假设我有一张表来跟踪是否错过了这样的付款:

+----+---------+------------+------------+---------+--------+
| id | loan_id | amount_due |   due_at   | paid_at | missed |
+----+---------+------------+------------+---------+--------+
|  1 |    1    |        100 | 2013-08-17 | NULL    | NULL   |
|  5 |    1    |        100 | 2013-09-17 | NULL    | NULL   |
|  7 |    1    |        100 | 2013-10-17 | NULL    | NULL   |
+----+---------+------------+------------+---------+--------+

并且,例如,我运行了一个查询,检查是否错过了这样的付款:

UPDATE loan_payments
SET missed = 1
WHERE DATEDIFF(NOW(), due_at) >= 10
AND paid_at IS NULL

然后假设id = 1的行受到影响。我希望将id = 1的行的amount_due添加到下一行的amount_due中,以便表格如下所示:

+----+---------+------------+------------+---------+--------+
| id | loan_id | amount_due |   due_at   | paid_at | missed |
+----+---------+------------+------------+---------+--------+
|  1 |       1 |        100 | 2013-08-17 | NULL    |      1 |
|  5 |       1 |        200 | 2013-09-17 | NULL    | NULL   |
|  7 |       1 |        100 | 2013-10-17 | NULL    | NULL   |
+----+---------+------------+------------+---------+--------+

有关如何做的任何建议吗?

由于

3 个答案:

答案 0 :(得分:0)

不幸的是我现在没有时间写出成熟的SQL,但是这里是我认为你需要实现的伪代码:

select all DISTINCT loan_id from table loan_payments

for each loan_id:
    set missed = 1 for all outstanding payments for loan_id (as determined by date)
    select the sum of all outstanding payments for loan_id
    add this sum to the amount_due for the loan's next due date after today

关于如何使用纯MySQL进行循环,请参阅此内容:http://dev.mysql.com/doc/refman/5.7/en/cursors.html

答案 1 :(得分:0)

我通过添加missed_at字段修复了我自己的问题。在将第一行更新为$now = 1和missed = missed_at之前,我将当前时间戳($now)放入变量中,然后运行此查询以更新下一行排amount_due

UPDATE loan_payments lp1 JOIN loan_payments lp2 ON lp1.due_at > lp2.due_at
SET lp1.amount_due = lp2.amount_due + lp1.amount_due
WHERE lp2.missed_at = $now AND DATEDIFF(lp1.due_at, lp2.due_at) <= DAYOFMONTH(LAST_DAY(lp1.due_at))

我希望我只能使用LIMIT 1来查询该查询,但事实证明UPDATE JOIN查询无法使用{{1}}。

总而言之,我使用了两个查询来实现我想要的目标。它成功了。

请告知您是否有更好的解决方案。

谢谢!

答案 2 :(得分:0)

看看这个:

SQL Fiddle

MySQL 5.5.32架构设置

CREATE TABLE loan_payments
    (`id` int, `loan_id` int, `amount_due` int, 
     `due_at` varchar(10), `paid_at` varchar(4), `missed` varchar(4))
;

INSERT INTO loan_payments
    (`id`, `loan_id`, `amount_due`, `due_at`, `paid_at`, `missed`)
VALUES
    (1, 1, 100, '2013-09-17', NULL, NULL),
    (3, 2, 100, '2013-09-17', NULL, NULL),
    (5, 1, 100, '2013-10-17', NULL, NULL),
    (7, 1, 100, '2013-11-17', NULL, NULL)
;

UPDATE loan_payments AS l
LEFT OUTER JOIN (SELECT loan_id, MIN(ID) AS ID
            FROM loan_payments
            WHERE DATEDIFF(NOW(), due_at) < 0
            GROUP BY loan_id) AS l2 ON l.loan_id = l2.loan_id
LEFT OUTER JOIN loan_payments AS l3 ON l2.id = l3.id
SET l.missed = 1, l3.amount_due = l3.amount_due + l.amount_due
WHERE DATEDIFF(NOW(), l.due_at) >= 10
AND l.paid_at IS NULL
;

查询1

SELECT *
FROM loan_payments

<强> Results

| ID | LOAN_ID | AMOUNT_DUE |     DUE_AT | PAID_AT | MISSED |
|----|---------|------------|------------|---------|--------|
|  1 |       1 |        100 | 2013-09-17 |  (null) |      1 |
|  3 |       2 |        100 | 2013-09-17 |  (null) |      1 |
|  5 |       1 |        200 | 2013-10-17 |  (null) | (null) |
|  7 |       1 |        100 | 2013-11-17 |  (null) | (null) |