Сукупна функція в запиті на оновлення 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.

Я мав це знати, але мій розум малює порожнім. Що я роблю неправильно?


Чудове питання ... я би хотів, щоб я міг підтримати більше одного разу.
Джо

Відповіді:


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  

40
Я поставив три запити поруч і склав план виконання. Ця відповідь мала вартість 5%.
Маргарет

Елегантний, простий у реалізації ... Де ти був цілий день ??? Я
стукаю

1
Важливо: Будьте уважні, якщо будь-яке з полів, за якими ви групуєтесь, може мати нульовий характер (наприклад, поле 3 вище). вам потрібно модифікувати «приєднатися» до рахунку для цього або ваші суми будуть неточними ( stackoverflow.com/a/14366034/16940 )
Simon_Weaver

10

Використання:

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

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%.
Маргарет

Окі-докі! І дякую за відгук. Я додаю його до свого набору інструментів. :-)
Паулу Сантос

Це було б тому, що ви використовуєте ПІДВИСОК, який повинен запускати SUM () кожен рядок, що є дійсним, навіть з оптимізатором
clifton_h

4

Хороша ситуація для використання ХРЕСТНОГО ЗАСТОСУВАННЯ

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, але будьте обережні при ОНОВЛЕННІ за допомогою 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


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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.