MySQL使用带有多个返回行的子查询更新字段值

时间:2010-12-10 21:23:08

标签: mysql join subquery

我有两张桌子“银行”和“债券”。每个用户都有一个银行记录,但可以有0个,1个或多个债券记录。

我想写一个脚本来更新“银行”表中的“现金”字段,其中包含用户可能拥有的多个债券的利益。利息由“债券”表的issuePrice * coupon字段计算。但是,由于用户可能持有多个债券,因此应该为每个债券执行此操作。

此刻,我尝试过这样的事情:

$MySQL->db_Query("UPDATE bonds bo, bank ba SET 
        ba.cash = ROUND(ba.cash + (bo.issuePrice * bo.coupon), 2), 
        ba.earned = ROUND(ba.earned + (bo.issuePrice * bo.coupon), 2) 
    WHERE LOWER(ba.user) = LOWER(bo.holder) AND 
        LOWER(bo.holder) <> LOWER('Bank');");

但它没有给出预期的结果。我试着用一个有2个债券的用户,如果两个债券每个都应该给500个利息,那么总共1000个,它只增加500个就像只有1个债券一样。如果我将一个债券设置为500个利息而另一个债券的计算利息为1000,则突然增加475个。

2 个答案:

答案 0 :(得分:1)

确保您的UPDATE语句尝试一次更新每个用户的行可能是值得的。子查询是执行此操作的最佳方式,最有效地实现为联接表:

UPDATE bank 
JOIN (SELECT LOWER(bonds.holder) as user,
    SUM(bonds.issuePrice * bonds.coupon) as total
    FROM bonds
    WHERE LOWER(bonds.holder) != 'bank'
    GROUP BY user
) as increments ON increments.user = LOWER(bank.user)
SET bank.cash = ROUND(bank.cash + increments.total, 2),
    bank.earned = ROUND(bank.earned + increments.total, 2)

(为了进行更多优化,可能应该删除LOWER和ROUND调用,但这是另一个讨论。)

答案 1 :(得分:0)

最直接的方法是使用子选择并单独更新字段...

UPDATE bank ba1
SET ba1.cash = ba1.cash + (ROUND(SELECT SUM(bo.issuePrice * bo.coupon)
               FROM bank ba2 JOIN bonds bo ON bo.user = ba2.user
               WHERE ba2.user = ba1.user), 2)
...