基于上一行循环的计算更新行

时间:2014-09-07 12:24:54

标签: php mysql for-loop foreach sql-update

我想更新行数不正确的人的行。

Num | Name| Date Paid  | pay |old | new
1   | jon | 2014-08-01 | 100 |150 | 250
2   | jon | 2014-08-02 | 50  |250 | 300
3   | jon | 2014-08-03 | 110 |300 | 410
4   | jon | 2014-08-07 | 60  |410 | 470
5   | jon | 2014-08-09 | 200 |410 | 470
6   | jon | 2014-08-10 | 10  |410 | 470
7   | jon | 2014-08-15 | 100 |410 | 470
8   | jon | 2014-08-17 | 20  |410 | 470

示例数据库是here

获取列数(新)的公式是第一个日期,即数字1是列(支付)+列(旧)=列(新):

100+150 = 250. 

然后250将被放入Old中的第二行,然后依此类推。

column(pay) + column(old) = column(new): 50 + 250 = 300. 

我想更新所有错误的数据。有没有办法更新它将循环或任何东西?感谢您的时间和帮助,有大约400多个数据是错误的:D

列(旧)的公式是前一列(新)的值,所以第5 - 8行的数据错误,列(旧)和列(新)是否有继续更新的方法?

2 个答案:

答案 0 :(得分:1)

您可以使用以下声明执行此操作:

UPDATE
    person p
INNER JOIN (
    SELECT
        p1.*, 
        p2.personID as p2id, 
        p2.oldpaidamount as old2, 
        p2.newpaidamount as new2
    FROM
        person p1
    INNER JOIN 
        person p2
    ON
        p1.personID > p2.personID
    AND
        p1.personName = p2.personName
    AND
        p2.personID = (
            SELECT 
                MAX(p3.personID)
            FROM
                person p3
            WHERE
                p3.personID < p1.personID
        )
    ) temp
ON
    p.personID = temp.personID
AND
    p.personName = temp.personName
SET
    p.newpaidAmount = temp.new2 + p.paidamount,   -- add this line to correct the newpaidamount
    p.oldpaidAmount = temp.new2
WHERE
    p.oldpaidAmount <> temp.new2

我们在同一个表上实现我们的子选择,以避免MySQL的限制,即在子选择中从一个表中选择时不能更新表。我使用INNER JOIN来获取所需的值,因为第一行不需要更新。

modified fiddle中查看它。

注意:
您不能使用UPDATE触发器来保持当前状态,因为UPDATE触发器会触发自身,因此您应该使用存储过程进行更新。对于INSERT操作,您可以使用BEFORE INSERT触发器来获取OldpaidAmount的正确值。

我的印象是,如果存储了payamounts的整个历史记录,那么这两列都是多余的(这里是150缺少150的起点)。

答案 1 :(得分:0)

    for($i=1;$i<=$totalnumberRows;$i++)
{

$mysqlUpdate = mysqli_query($con, "UPDATE
    person p
INNER JOIN (
    SELECT
        p1.*, 
        p2.personID as p2id, 
        p2.paidamount as paid2, 
        p2.oldpaidamount as old2, 
        p2.newpaidamount as new2
    FROM
        person p1
    INNER JOIN 
        person p2
    ON
        p1.personID > p2.personID
    AND
        p1.personName = p2.personName
    AND
        p2.personID = (
            SELECT 
                MAX(p3.personID)
            FROM
                person p3
            WHERE
                p3.personID < p1.personID 
                AND p3.personName = 'jon'
        )
    WHERE p1.personName = 'jon'

    ) temp
ON
    p.personID = temp.personID
AND
    p.personName = temp.personName
SET
    p.oldpaidAmount = temp.new2,
    p.newpaidAmount = temp.new2 + p.paidAmount");

}

totalnumberRows将循环显示它将更新到最后一行的次数..致@VMai的信用

这是sqlfiddle中的代码LINK!!它有很多更新查询,因为我现在不知道如何在sqlfiddle中循环,但在php中你可以使用forloop来做到这一点,谢谢......