2008-11-14 8 views
17

Mam tabelę główną/szczegółową i chcę zaktualizować niektóre wartości podsumowania w tabeli głównej w odniesieniu do tabeli szczegółów. Wiem, że mogę zaktualizować je tak:Zaktualizuj wiele wartości w pojedynczej instrukcji.

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) 

Ale chciałbym to zrobić w jednym rachunku, mniej więcej tak:

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 

ale to nie działa. Próbowałem także wersji, które pomijają klauzulę "grupuj według". Nie jestem pewien, czy napotykam na ograniczenia mojej konkretnej bazy danych (Advantage), czy na ograniczenia mojego SQL. Prawdopodobnie to drugie. Czy ktoś może pomóc?

Odpowiedz

3

Dlaczego robisz grupę za pomocą instrukcji aktualizacji? Czy na pewno nie jest to ta część, która powoduje błąd zapytania? Spróbuj tego:

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

@Chris, to też nie działa dla mnie. Jeśli to działa dla ciebie, prawdopodobnie wpadnę na ograniczenie mojej konkretnej bazy danych. – Kluge

+0

Wyjaśniłem teraz moje oryginalne pytanie, aby pokazać, że próbowałem pominąć klauzulę "grupuj według". Dzięki! – Kluge

+0

Jakiego serwera/wersji bazy danych używasz? Kiedy mówisz o moim SQL, masz na myśli "moje umiejętności SQL" lub "mySQL, serwer"? – Chris

2

Próbowałeś z sub-kwerendy dla każdej dziedzinie:

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, masz rację, to by działało.Ale przypuszczam, że nie byłoby to szybsze niż trzy instrukcje w moim przykładzie.Myślę, że powinienem pójść wypróbować oba sposoby i porównać czasy. – Kluge

18

spróbuj tego:

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 

zależności od bazy danych, którego używasz, jeśli to robi Działa, a następnie spróbuj tego (jest to niestandardowy SQL, ale legalny w 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

Próbowałem obu z twoich podejść i nie mógł ich zmusić do pracy.Moje bazy danych obsługuje tylko SQL-92 z kilkoma rozszerzeniami.Jakie bazy danych używasz, który obsługuje kod, który sugerujesz? – Kluge

+0

Serwer SQL obsługuje tę składnię ... Jeśli twoja baza danych nie wesprzyj to, a następnie myślę, że utknąłeś z wieloma podejściami podkwerendy .. zalecanymi przez Milena poniżej –

+2

To nie jest legalny SQL.Nie ma klauzuli "FROM" w aktualizacji http://dev.mysql.com/ doc/refman/6.0/en/update.html –

2

Spróbuj tego:

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

W Oracle rozwiązaniem byłoby:

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

Nie wiem, czy system pozwala na to samo.

+0

Moja baza danych na to nie pozwala, ale miło jest zobaczyć podejście, jakie podjęli inni dostawcy baz danych. – Kluge

0

Jeśli twój DB obsługuje to, łączenie wszystkich 3 aktualizacji w jeden łańcuch sql pozwoli zaoszczędzić na wycieczkach serwerowych w przypadku zapytań przez sieć LAN. Więc jeśli nic innego nie działa, może to dać ci niewielką poprawę. Typowym ogranicznikiem wielostronicowym jest średnik, np .:

'update x....;update y...;update...z' 
Powiązane problemy