Обновить несколько значений в одном операторе - PullRequest
21 голосов
/ 14 ноября 2008

У меня есть основная / подробная таблица и я хочу обновить некоторые сводные значения в основной таблице по сравнению с подробной таблицей. Я знаю, что могу обновить их так:

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. Вероятно, последний. Кто-нибудь может помочь?

Ответы [ 6 ]

24 голосов
/ 14 ноября 2008

Попробуйте это:

 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
5 голосов
/ 14 ноября 2008

Почему вы делаете группу в заявлении об обновлении? Вы уверены, что это не та часть, которая вызывает сбой запроса? Попробуйте это:

update 
    MasterTbl
set
    TotalX = Sum(DetailTbl.X),
    TotalY = Sum(DetailTbl.Y),
    TotalZ = Sum(DetailTbl.Z)
from
    DetailTbl
where
    DetailTbl.MasterID = MasterID
4 голосов
/ 14 ноября 2008

В Oracle решение будет:

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

Не знаю, допускает ли ваша система то же самое.

3 голосов
/ 14 ноября 2008

Вы пробовали с подзапросом для каждого поля:

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
    ....
2 голосов
/ 14 ноября 2008

Попробуйте это:

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
0 голосов
/ 05 мая 2010

Если ваша БД поддерживает это, объединение всех трех обновлений в одну строку sql сэкономит на обходах сервера при запросах по локальной сети. Так что, если ничего не работает, это может дать вам небольшое улучшение. Типичным разделителем для нескольких операторов является точка с запятой, например:

'update x....;update y...;update...z'
...