web-dev-qa-db-fra.com

Mettre à jour plusieurs valeurs dans une seule instruction

J'ai une table maître/détail et je souhaite mettre à jour certaines valeurs récapitulatives de la table maître par rapport à la table détail. Je sais que je peux les mettre à jour comme ceci:

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)

Mais je voudrais le faire en une seule déclaration, quelque chose comme ceci:

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

mais ça ne marche pas. J'ai également essayé des versions qui omettent la clause "group by" . Je ne sais pas si je me heurte aux limites de ma base de données particulière (Advantage) ou à celles de mon code SQL. Probablement le dernier. Quelqu'un peut-il aider?

20
Kluge

Essaye ça:

 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

En fonction de la base de données utilisée, si cela ne fonctionne pas, essayez ceci (c'est du SQL non standard mais légal dans 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
22
Charles Bretana

Pourquoi faites-vous un groupe par sur une déclaration de mise à jour? Êtes-vous sûr que ce n'est pas la partie à l'origine de l'échec de la requête? Essaye ça:

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

Dans Oracle, la solution serait:

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

Je ne sais pas si votre système permet la même chose.

4
Dave Costa

Avez-vous essayé avec une sous-requête pour chaque champ:

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
    ....
3
Milen A. Radev

Essaye ça:

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
2
Martin York

Si votre base de données le prend en charge, la concaténation des 3 mises à jour dans une chaîne SQL économise les allers-retours entre serveurs si vous interrogez sur le réseau local. Donc, si rien ne fonctionne, cela pourrait vous apporter une légère amélioration. Le délimiteur multi-instructions typique est le point-virgule, par exemple:

'update x....;update y...;update...z'
0
andora