Агрегатная функция в запросе обновления SQL?

98

Я пытаюсь установить значение в одной таблице как сумму значений в другой таблице. Что-то в этом роде:

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

Конечно, в таком виде это не сработает - SETне поддерживает SUMи не поддерживает GROUP BY.

Я должен это знать, но в моей голове пусто. Что я делаю не так?

Маргарет
источник
Отличный вопрос ... Хотел бы я проголосовать больше одного раза.
Джо

Ответы:

149
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
источник
41
Я поместил три запроса рядом и составил план выполнения. Этот ответ стоил 5%.
Маргарет
Элегантно, легко реализовать ... Где ты был весь день ??? Я стучал головой над ним больше часа сейчас :)
Ange1
1
Важно: обратите внимание, может ли какое-либо из полей, по которым вы группируете, допускать значение NULL (например, field3 выше). вам нужно будет изменить 'join', чтобы учесть это, иначе ваши суммы будут неточными ( stackoverflow.com/a/14366034/16940 )
Simon_Weaver
10

Использование:

UPDATE table1
   SET field1 = (SELECT SUM(t2.field2) 
                   FROM TABLE2 t2 
                  WHERE t2.field3 = field2)
OMG Пони
источник
14
Я поместил три запроса рядом и составил план выполнения. Стоимость этого ответа составила 44%.
Маргарет
это не сработало для меня, потому что t2.filed3 было тем же именем, что и table1.field2, поэтому соединение, выполняемое за кулисами, не работало должным образом. (Я предполагаю, что за кулисами есть соединение)
Джо
5

Или вы можете использовать смесь ответов JBrooks и OMG Ponies :

UPDATE table1
   SET field1 = (SELECT SUM(field2)
                   FROM table2 AS t2
                  WHERE t2.field3 = t1.field3)
  FROM table1 AS t1
Пауло Сантос
источник
16
Я поместил три запроса рядом и составил план выполнения. Стоимость этого ответа составила 51%.
Маргарет
Окей! И спасибо за отзыв. Я добавлю его в свой набор инструментов. :-)
Пауло Сантос
Это было бы потому, что вы используете SUBQUERY, который должен
запускать
4

Хорошая ситуация для использования 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
Джонатан Робертс
источник
3

Я знаю, что вопрос помечен как SQL Server, но будьте осторожны с UPDATE с JOIN, если вы используете PostgreSQL . Ответ @JBrooks не сработает:

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

Вам придется адаптировать его к:

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

См. Параметр from_listв документации, чтобы узнать, почему FROMPostgreSQL считает, что это самоподключение: https://www.postgresql.org/docs/9.5/static/sql-update.html#AEN89239

Bludwarf
источник
0

Вы также можете использовать CTE, как показано ниже.

;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
Каран
источник