2008-11-14 68 views
17

Tôi có bảng chính/chi tiết và muốn cập nhật một số giá trị tóm tắt trong bảng chính so với bảng chi tiết. Tôi biết tôi có thể cập nhật chúng như thế này:Cập nhật nhiều giá trị trong một câu lệnh

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) 

Nhưng, tôi muốn làm điều đó trong một tuyên bố duy nhất, một cái gì đó như thế này:

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 

nhưng điều đó không làm việc. Tôi cũng đã thử các phiên bản bỏ qua mệnh đề "nhóm theo". Tôi không chắc liệu tôi có gặp phải các giới hạn của cơ sở dữ liệu cụ thể (Advantage) hay các giới hạn của SQL của tôi hay không. Có lẽ sau này. Có ai giúp được không?

Trả lời

3

Tại sao bạn làm một nhóm theo một tuyên bố cập nhật? Bạn có chắc đó không phải là phần khiến truy vấn thất bại không? Hãy thử điều này:

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

@Chris, cũng không có tác dụng đối với tôi. Nếu nó phù hợp với bạn, thì có lẽ tôi sẽ gặp phải một hạn chế về cơ sở dữ liệu cụ thể của tôi. – Kluge

+0

Bây giờ tôi đã làm rõ câu hỏi ban đầu của mình để cho thấy rằng tôi đã thử bỏ qua mệnh đề "nhóm theo". Cảm ơn! – Kluge

+0

Bạn đang sử dụng máy chủ/phiên bản cơ sở dữ liệu nào? Khi bạn nói SQL của tôi, bạn có nghĩa là "kỹ năng SQL của tôi" hay "mySQL, máy chủ"? – Chris

2

Bạn đã thử với một truy vấn phụ cho mọi lĩnh vực:

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, Bạn nói đúng, điều đó có hiệu quả.Tuy nhiên, tôi cho rằng nó sẽ không nhanh hơn ba câu trong ví dụ của tôi. Tôi đoán là tôi nên thử cả hai cách và so sánh thời gian. – Kluge

18

Hãy thử điều này:

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 

Tùy thuộc vào cơ sở dữ liệu bạn đang sử dụng, nếu điều đó không 't làm việc, sau đó thử này (đây là SQL không chuẩn nhưng hợp pháp trong 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

Tôi đã thử cả hai Cơ sở dữ liệu của tôi chỉ hỗ trợ SQL-92 với một vài phần mở rộng Cơ sở dữ liệu nào bạn đang sử dụng hỗ trợ mã bạn đề xuất? – Kluge

+0

SQL Server hỗ trợ cú pháp này ... Nếu cơ sở dữ liệu của bạn không hỗ trợ điều này, sau đó tôi nghĩ rằng bạn đang bị mắc kẹt với các phương pháp tiếp cận subquery nhiều .. theo khuyến cáo của Milen dưới đây –

+2

Đây không phải là SQL hợp pháp.Không có mệnh đề 'FROM' trong bản cập nhật. http://dev.mysql.com/ doc/refman/6.0/en/update.html –

2

Hãy thử điều này:

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

Trong Oracle giải pháp sẽ là:

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

Không biết nếu hệ thống của bạn cho phép như vậy.

+0

Cơ sở dữ liệu của tôi không cho phép điều đó, nhưng thật tuyệt khi thấy cách tiếp cận các nhà cung cấp cơ sở dữ liệu khác đã thực hiện. – Kluge

0

Nếu DB của bạn hỗ trợ, nối tất cả 3 cập nhật vào một chuỗi sql sẽ lưu trên các chuyến đi vòng quanh máy chủ nếu truy vấn qua mạng LAN. Vì vậy, nếu không có gì khác hoạt động, điều này có thể cung cấp cho bạn một chút cải thiện. Dấu phân tách đa câu lệnh điển hình là dấu chấm phẩy, ví dụ:

'update x....;update y...;update...z' 
Các vấn đề liên quan