web-dev-qa-db-ja.com

単一のステートメントで複数の値を更新する

マスター/詳細テーブルがあり、マスターテーブルの一部のサマリー値を詳細テーブルに対して更新したい。私は次のようにそれらを更新できることを知っています:

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)

しかし、私は次のような単一のステートメントでそれをしたいと思います:

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

しかし、それは機能しません。 「group by」句を省略したバージョンも試しました。特定のデータベースの制限(Advantage)に突き当たるのか、SQLの制限に突き当たるのかわかりません。おそらく後者。誰でも助けることができますか?

23
Kluge

これを試して:

 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

使用しているデータベースに応じて、それが機能しない場合は、これを試してください(これは非標準のSQLですが、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
25
Charles Bretana

更新ステートメントでグループ化するのはなぜですか?クエリが失敗する原因になっているのは確かではありませんか?これを試して:

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

Oracleのソリューションは次のとおりです。

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

システムで同じことが許可されているかどうかはわかりません。

4
Dave Costa

すべてのフィールドに対してサブクエリを試しましたか:

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

これを試して:

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

DBがそれをサポートしている場合、3つの更新すべてを1つのsql文字列に連結すると、LAN経由でクエリを実行する場合のサーバーラウンドトリップが節約されます。したがって、他に何も機能しない場合は、これにより少し改善される可能性があります。典型的な「複数ステートメントの区切り文字はセミコロンです。例:

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