Aggregatfunktion in einer SQL-Update-Abfrage?

98

Ich versuche, den Wert in einer Tabelle auf die Summe der Werte in einer anderen Tabelle zu setzen. Etwas in diese Richtung:

UPDATE table1
SET field1 = SUM(table2.field2)
FROM table1
INNER JOIN table2 ON table1.field3 = table2.field3
GROUP BY table1.field3

Natürlich wird es derzeit nicht funktionieren - SETes wird nicht unterstützt SUMund es wird nicht unterstützt GROUP BY.

Ich sollte das wissen, aber meine Gedanken zeichnen eine Lücke. Was mache ich falsch?

Margaret
quelle
Tolle Frage ... ich wünschte, ich könnte mehr als einmal abstimmen.
Joe

Antworten:

148
UPDATE t1
SET t1.field1 = t2.field2Sum
FROM table1 t1
INNER JOIN (select field3, sum(field2) as field2Sum
   from table2
  group by field3) as t2
on t2.field3 = t1.field3  
JBrooks
quelle
40
Ich habe die drei Abfragen nebeneinander gestellt und einen Ausführungsplan erstellt. Diese Antwort kostete 5%.
Margaret
Elegant, einfach zu implementieren ... Wo warst du den ganzen Tag ??? Ich habe jetzt seit mehr als einer Stunde meinen Kopf darüber geschlagen :)
Ange1
1
Wichtig: Achten Sie darauf, ob eines der Felder, nach denen Sie gruppieren, möglicherweise nullwertfähig ist (z. B. Feld 3 oben). Sie müssten den 'Join' ändern, um dies zu berücksichtigen, oder Ihre Summen sind ungenau ( stackoverflow.com/a/14366034/16940 )
Simon_Weaver
10

Verwenden:

UPDATE table1
   SET field1 = (SELECT SUM(t2.field2) 
                   FROM TABLE2 t2 
                  WHERE t2.field3 = field2)
OMG Ponys
quelle
14
Ich habe die drei Abfragen nebeneinander gestellt und einen Ausführungsplan erstellt. Diese Antwort kostete 44%.
Margaret
Dies funktionierte bei mir nicht, da t2.filed3 den gleichen Namen wie table1.field2 hatte und der hinter den Kulissen durchgeführte Join nicht ordnungsgemäß funktionierte. (Ich nehme an, es gibt eine Verbindung hinter den Kulissen)
Joe
5

Oder Sie könnten eine Mischung aus Antworten von JBrooks und OMG Ponies verwenden :

UPDATE table1
   SET field1 = (SELECT SUM(field2)
                   FROM table2 AS t2
                  WHERE t2.field3 = t1.field3)
  FROM table1 AS t1
Paulo Santos
quelle
16
Ich habe die drei Abfragen nebeneinander gestellt und einen Ausführungsplan erstellt. Diese Antwort kostete 51%.
Margaret
Okie dokie! Und danke für das Feedback. Ich werde es meiner Toolbox hinzufügen. :-)
Paulo Santos
Das liegt daran, dass Sie eine SUBQUERY verwenden, die die SUM () in jeder gültigen Zeile auslösen muss, auch mit dem Optimierer
clifton_h
4

Eine gute Situation, um CROSS APPLY zu verwenden

UPDATE t1
   SET t1.field1 = t2.field2Sum
  FROM table1 t1
 CROSS APPLY (SELECT SUM(field2) as field2Sum
                FROM table2 t2
               WHERE t2.field3 = t1.field3) AS t2
Jonathan Roberts
quelle
3

Ich weiß, dass die Frage mit SQL Server gekennzeichnet ist, aber seien Sie vorsichtig mit UPDATE mit JOIN, wenn Sie PostgreSQL verwenden . @JBrooks Antwort wird nicht funktionieren:

UPDATE t1
SET t1.field1 = t2.field2Sum
FROM table1 t1
INNER JOIN (...) as t2
on t2.field3 = t1.field3  

Sie müssen es anpassen an:

UPDATE table1 t1
SET t1.field1 = t2.field2Sum
FROM (...) as t2
WHERE t2.field3 = t1.field3  

Unter Parameter from_listim Dokument erfahren Sie, warum FROMPostgreSQL als Self-Join betrachtet wird: https://www.postgresql.org/docs/9.5/static/sql-update.html#AEN89239

Bludwarf
quelle
0

Sie können CTE auch wie unten verwenden.

;WITH t2 AS (
    SELECT field3, SUM(field2) AS field2
    FROM table2
    GROUP BY field3
)
UPDATE table1
SET table1.field1 = t2.field2
FROM table1
INNER JOIN t2 ON table1.field3 = t2.field3
Karan
quelle