2008-11-14 33 views
17

Tengo una tabla maestra/de detalles y quiero actualizar algunos valores de resumen en la tabla maestra con la tabla de detalles. Sé que puedo actualizarlos como esto:Actualizar valores múltiples en una sola instrucción

update MasterTbl set TotalX = (select sum(X) from DetailTbl where DetailTbl.MasterID = MasterTbl.ID) 
update MasterTbl set TotalY = (select sum(Y) from DetailTbl where DetailTbl.MasterID = MasterTbl.ID) 
update MasterTbl set TotalZ = (select sum(Z) from DetailTbl where DetailTbl.MasterID = MasterTbl.ID) 

Pero, me gustaría hacerlo en una sola instrucción, algo como esto:

update MasterTbl set TotalX = sum(DetailTbl.X), TotalY = sum(DetailTbl.Y), TotalZ = sum(DetailTbl.Z) 
from DetailTbl 
where DetailTbl.MasterID = MasterTbl.ID group by MasterID 

pero que no funciona. También probé versiones que omiten la cláusula "agrupar por". No estoy seguro de si estoy tropezando con los límites de mi base de datos particular (Ventaja), o los límites de mi SQL. Probablemente el último. ¿Alguien puede ayudar?

Respuesta

3

¿Por qué haces un grupo en una declaración de actualización? ¿Estás seguro de que esa no es la parte que está causando que la consulta falle? Prueba esto:

update 
    MasterTbl 
set 
    TotalX = Sum(DetailTbl.X), 
    TotalY = Sum(DetailTbl.Y), 
    TotalZ = Sum(DetailTbl.Z) 
from 
    DetailTbl 
where 
    DetailTbl.MasterID = MasterID 
+0

@Chris, eso tampoco me funciona. Si funciona para usted, entonces probablemente me encuentre con una limitación de mi base de datos en particular. – Kluge

+0

He aclarado mi pregunta original para mostrar que he intentado omitir la cláusula "agruparme". ¡Gracias! – Kluge

+0

¿Qué servidor/versión de base de datos está usando? Cuando dices mi SQL, ¿te refieres a "mis habilidades SQL" o "mySQL, el servidor"? – Chris

2

Ha intentado con una sub-consulta para cada campo:

UPDATE 
    MasterTbl 
SET 
    TotalX = (SELECT SUM(X) from DetailTbl where DetailTbl.MasterID = MasterTbl.ID), 
    TotalY = (SELECT SUM(Y) from DetailTbl where DetailTbl.MasterID = MasterTbl.ID), 
    TotalZ = (SELECT SUM(Z) from DetailTbl where DetailTbl.MasterID = MasterTbl.ID) 
WHERE 
    .... 
+0

@Milen, tienes razón, eso funcionaría. Sin embargo, supongo que no sería más rápido que las tres afirmaciones de mi ejemplo. Creo que debería probar ambas formas y comparar los tiempos. – Kluge

18

intente esto:

Update MasterTbl Set 
    TotalX = Sum(D.X),  
    TotalY = Sum(D.Y),  
    TotalZ = Sum(D.Z) 
From MasterTbl M Join DetailTbl D 
    On D.MasterID = M.MasterID 

Dependiendo de la base de datos que está utilizando, si es que doesn no funciona, entonces intente esto (esto es SQL no estándar pero legal en SQL Server):

Update M Set 
    TotalX = Sum(D.X),  
    TotalY = Sum(D.Y),  
    TotalZ = Sum(D.Z) 
From MasterTbl M Join DetailTbl D 
    On D.MasterID = M.MasterID 
+0

Intenté ambos de sus enfoques y no podría hacer que funcionen. Mi base de datos solo es compatible con SQL-92 con algunas extensiones. ¿Qué base de datos está utilizando que admita el código que sugiere? – Kluge

+0

SQL Server admite esta sintaxis ... Si su base de datos no lo hace Respalde esto, entonces creo que está atascado con el enfoque de subconsulta múltiple ... como lo recomienda Milen por debajo de –

+2

Este no es SQL legal. No hay una cláusula 'FROM' en una actualización. http://dev.mysql.com/ doc/refman/6.0/es/update.html –

2

Prueba esto:

update MasterTbl M, 
     (select sum(X) as sX, 
       sum(Y) as sY, 
       sum(Z) as sZ, 
       MasterID 
     from DetailTbl 
     group by MasterID) A 
set 
    M.TotalX=A.sX, 
    M.TotalY=A.sY, 
    M.TotalZ=A.sZ 
where 
    M.ID=A.MasterID 
3

En Oracle la solución sería:

UPDATE 
    MasterTbl 
SET 
    (TotalX,TotalY,TotalZ) = 
     (SELECT SUM(X),SUM(Y),SUM(Z) 
     from DetailTbl where DetailTbl.MasterID = MasterTbl.ID) 

No sabe si el sistema permite la misma.

+0

Mi base de datos no lo permite, pero es agradable ver el enfoque que otros proveedores de bases de datos han tomado. – Kluge

0

Si su base de datos lo admite, la concatenación de las 3 actualizaciones en una cadena sql se guardará en los viajes de ida y vuelta del servidor si se realiza una consulta a través de la LAN. Entonces, si nada funciona, esto podría darle una ligera mejoría. El 'delimitador de varias declaraciones' típico es el punto y coma, por ejemplo:

'update x....;update y...;update...z' 
Cuestiones relacionadas