2011-01-27 12 views
8
UPDATE user 
SET balance = balance + p.amount 
FROM payments p WHERE user.id = p.user_id AND p.id IN (36,38,40) 

に参加しかし、それはバランスに加え、最初の支払い1936年 の値のみの量私はコード内のサイクルを作りたくない、それを修正する方法を私を助けてください多くの要求を実行するPostgreSQLのUPDATE - 左とクエリが問題

答えて

19

複数のテーブルUPDATEでは、ターゲットテーブルの各ローは、ジョインによって複数回戻されても、1回だけ更新されます。より

docs

FROM句が存在する場合、どのような本質的に起こることは、ターゲットテーブルはfromlistで述べたテーブルに結合されていることであり、結合の各出力行が更新操作を表しますターゲット表の場合。 FROMを使用する場合は、変更する行ごとに最大で1つの出力行が生成されるようにする必要があります。言い換えると、ターゲット行は、他の表から複数の行に結合すべきではありません。存在する場合、結合行の1つだけがターゲット行を更新するために使用されますが、どちらが使用されるかは容易に予測できません。

使用この代わりに:

UPDATE user u 
SET  balance = balance + p.amount 
FROM (
     SELECT user_id, SUM(amount) AS amount 
     FROM payment 
     WHERE id IN (36, 38, 40) 
     GROUP BY 
       user_id 
     ) p 
WHERE u.id = p.user_id 
+0

'p'は未定義です。 –

+4

no -pは副選択の別名です。完全に定義されています。 – Rob