119

I'm trying to set the value in one table to the sum of the values in another table. Something along these lines:

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

Of course, as this stands, it won't work - SET doesn't support SUM and it doesn't support GROUP BY.

I should know this, but my mind's drawing a blank. What am I doing wrong?

0

6 Answers 6

172
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  
Sign up to request clarification or add additional context in comments.

4 Comments

I put the three queries side-by-side and ran an execution plan. This answer had a cost of 5%.
Elegant, easy to implement...Where have you been all day??? I have been banging my head over it for more than an hour now :)
Important: Watch out if any of the fields you are grouping by might be nullable (eg. field3 above). you'd need to modify the 'join' to account for this or your sums will be inaccurate (stackoverflow.com/a/14366034/16940)
This is not working in postgresql. You must do it like in this post here: stackoverflow.com/questions/35393706/…
13

Use:

UPDATE table1
   SET field1 = (SELECT SUM(t2.field2) 
                   FROM TABLE2 t2 
                  WHERE t2.field3 = field2)

2 Comments

I put the three queries side-by-side and ran an execution plan. This answer had a cost of 44%.
this didn't work for me, because t2.filed3 was the same name as table1.field2, so the join performed behind the scenes didn't work properly. (I assuem there's a join behind the scenes)
9

A good situation to use CROSS APPLY

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

2 Comments

CROSS APPLY is elegant way and you can populate multiple columns as well.
I suggest to rename "t2" alias (CROSS APPLY product) into "f_sum" as you're applying a function against "t1" table. Using "t2" both as table2 alias and CROSS APPLY product alias can be misleading for the readers.
6

Or you could use a mix of JBrooks and OMG Ponies answers:

UPDATE table1
   SET field1 = (SELECT SUM(field2)
                   FROM table2 AS t2
                  WHERE t2.field3 = t1.field3)
  FROM table1 AS t1

3 Comments

I put the three queries side-by-side and ran an execution plan. This answer had a cost of 51%.
Okie dokie! And thanks for the feedback. I'll add it to my toolbox. :-)
That would be because you are using a SUBQUERY that must fire off the SUM() every row that is valid, even with the optimizer
4

I know the question is tagged SQL Server but be careful with UPDATE with JOIN if you are using PostgreSQL. @JBrooks answer won't work :

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

You will have to adapt it to :

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

See parameter from_list in the doc to get why FROM is considered by PostgreSQL as a self-join : https://www.postgresql.org/docs/9.5/static/sql-update.html#AEN89239

Comments

3

You can also use CTE like below.

;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

1 Comment

I used to do the update with subquery till I faced a situation today where subquery table needed outer table for a join. This is what works best in that case.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.