¿Función agregada en una consulta de actualización SQL?

98

Estoy tratando de establecer el valor en una tabla con la suma de los valores en otra tabla. Algo en estas líneas:

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

Por supuesto, tal como está, no funcionará, SETno es compatible SUMy no es compatible GROUP BY.

Debería saber esto, pero mi mente se está quedando en blanco. ¿Qué estoy haciendo mal?

Margaret
fuente
Gran pregunta ... me gustaría poder votar más de una vez.
Joe

Respuestas:

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
fuente
40
Puse las tres consultas una al lado de la otra y ejecuté un plan de ejecución. Esta respuesta tuvo un costo del 5%.
Margaret
Elegante, fácil de implementar ... ¿Dónde has estado todo el día ??? Me he estado golpeando la cabeza por más de una hora :)
Ange1
1
Importante: tenga cuidado si alguno de los campos por los que está agrupando puede ser anulable (por ejemplo, field3 arriba). necesitaría modificar el 'unirse' para tener en cuenta esto o sus sumas serán inexactas ( stackoverflow.com/a/14366034/16940 )
Simon_Weaver
10

Utilizar:

UPDATE table1
   SET field1 = (SELECT SUM(t2.field2) 
                   FROM TABLE2 t2 
                  WHERE t2.field3 = field2)
Ponis dios mio
fuente
14
Puse las tres consultas una al lado de la otra y ejecuté un plan de ejecución. Esta respuesta tuvo un costo del 44%.
Margaret
esto no funcionó para mí, porque t2.filed3 era el mismo nombre que table1.field2, por lo que la combinación realizada detrás de escena no funcionó correctamente. (Supongo que hay una unión detrás de escena)
Joe
5

O puede usar una combinación de respuestas de JBrooks y OMG Ponies :

UPDATE table1
   SET field1 = (SELECT SUM(field2)
                   FROM table2 AS t2
                  WHERE t2.field3 = t1.field3)
  FROM table1 AS t1
Paulo Santos
fuente
16
Puse las tres consultas una al lado de la otra y ejecuté un plan de ejecución. Esta respuesta tuvo un costo del 51%.
Margaret
¡De acuerdo ♥! Y gracias por los comentarios. Lo agregaré a mi caja de herramientas. :-)
Paulo Santos
Eso sería porque está utilizando una SUBQUERY que debe disparar SUM () cada fila que sea válida, incluso con el optimizador
clifton_h
4

Una buena situación para usar 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
Jonathan Roberts
fuente
3

Sé que la pregunta está etiquetada como SQL Server, pero tenga cuidado con UPDATE with JOIN si está utilizando PostgreSQL . La respuesta de @JBrooks no funcionará:

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

Tendrás que adaptarlo a:

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

Consulte el parámetro from_listen el documento para saber por qué FROMPostgreSQL lo considera una autounión: https://www.postgresql.org/docs/9.5/static/sql-update.html#AEN89239

Bludwarf
fuente
0

También puede utilizar CTE como se muestra a continuación.

;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
fuente