2010-12-10 13 views
0

Ich habe zwei Tabellen "Bank" und "Anleihen". Jeder Benutzer hat einen Bankdatensatz, kann aber 0, 1 oder mehr Bonds-Datensätze haben.MySQL Aktualisieren Sie einen Feldwert mit Unterabfrage mit mehreren Zeilen

Ich möchte ein Skript schreiben, das das Feld "Bargeld" in der Tabelle "Bank" mit den Interessen der Mehrfachbindungen aktualisiert, die ein Benutzer halten könnte. Die Verzinsung berechnet sich nach den Ausgabepreis * Couponfeldern der Tabelle "Obligationen". Da ein Benutzer jedoch mehrere Anleihen halten kann, sollte er dies für jede Anleihe tun.

Im Moment habe ich versucht, so etwas wie dieses:

$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');"); 

Aber es ist nicht das erwartete Ergebnis geben. Ich habe es mit einem Benutzer mit 2 Bonds versucht, wenn beide Bonds jeweils 500 Zinsen geben sollten, also insgesamt 1000, es addiert nur 500, wie es nur 1 Bonds gibt. Wenn ich eine Anleihen als 500 Zinsen und das andere mit einem berechneten Zinsen von 1000 festgelegt, fügt plötzlich 475.

+2

Convert es zu einem SELECT, und bestätigen Sie die Ausgabe ist, was Sie erwarten –

Antwort

1

Es ist wahrscheinlich sinnvoll, sicherzustellen, dass Ihre UPDATE-Anweisung versucht, die Zeile jedes Benutzers genau einmal zu aktualisieren. Eine Unterabfrage ist der beste Weg, dies zu tun, am effizientesten als Join-Tabelle implementiert:

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) 

(Für weitere Optimierung, die unteren und ROUND Anrufe wahrscheinlich eliminiert werden sollten, aber das ist eine andere Diskussion.)

+0

Danke, das hat funktioniert! –

0

Die straighforward Weg ist Unter wählt zu verwenden und die Felder einzeln aktualisieren ...

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) 
... 
+0

Dies funktioniert auch, aber ich denke, die andere Abfrage ist einfacher und leistungsfähiger. –

Verwandte Themen