2012-07-19 17 views
36

Mam następujące CTE, które da mi DocTotal dla całej faktury.Aktualizuj zapisy w tabeli z CTE

;WITH CTE_DocTotal 
AS 
(
    SELECT SUM(Sale + VAT) AS DocTotal 
    FROM PEDI_InvoiceDetail 
    GROUP BY InvoiceNumber 
) 

UPDATE PEDI_InvoiceDetail 
SET DocTotal = CTE_DocTotal.DocTotal 

Teraz z tym wynikiem chcę wprowadzić w kolumnie wartość DocTotal wewnątrz PEDI_InvoiceDetail.

Wiem, że nie zadziała i wiem, że czegoś brakuje, co to jest?

+0

wybrałem opcję CTE dla lepszej wydajności. – Etienne

Odpowiedz

69

Aktualizacje dokonywane w CTE będą kaskadowo do tabeli źródłowej.

Musiałem trochę odgadnąć przy Twoim schemacie, ale coś takiego powinno zadziałać.

;WITH T AS 
( SELECT InvoiceNumber, 
      DocTotal, 
      SUM(Sale + VAT) OVER(PARTITION BY InvoiceNumber) AS NewDocTotal 
    FROM PEDI_InvoiceDetail 
) 
UPDATE T 
SET  DocTotal = NewDocTotal 
+0

Czy Atom CTE UPDATE jest atomowy, jeśli uruchomione zapytania kwerendowe będą te same rekordy aktualizowane dwukrotnie? –

+0

Aktualizacja CTE nie różni się wcale od zwykłej aktualizacji. Jest atomowy i zajmie te same blokady tabeli/rzędu. To nic więcej niż cukier syntaktyczny – GarethD

16

Nie trzeba CTE dla tego

UPDATE PEDI_InvoiceDetail 
SET 
    DocTotal = v.DocTotal 
FROM 
    PEDI_InvoiceDetail 
inner join 
(
    SELECT InvoiceNumber, SUM(Sale + VAT) AS DocTotal 
    FROM PEDI_InvoiceDetail 
    GROUP BY InvoiceNumber 
) v 
    ON PEDI_InvoiceDetail.InvoiceNumber = v.InvoiceNumber 
+0

Ale jaki jest właściwy sposób to zrobić? Który jest szybszy? Który jest bardziej czytelny? – Zack

+3

@Zack "Poprawność" i "czytelność" w SQL są do pewnego stopnia subiektywne i kwestią gustu. Jednak niektóre historyczne wersje serwera SQL nie zawierają funkcji CTE. – podiluska

+0

SQLite3 3.8.11.1 narzeka: Błąd: w pobliżu "FROM": błąd składni –

23
WITH CTE_DocTotal (DocTotal, InvoiceNumber) 
AS 
(
    SELECT InvoiceNumber, 
      SUM(Sale + VAT) AS DocTotal 
    FROM PEDI_InvoiceDetail 
    GROUP BY InvoiceNumber 
)  
UPDATE PEDI_InvoiceDetail 
SET PEDI_InvoiceDetail.DocTotal = CTE_DocTotal.DocTotal 
FROM CTE_DocTotal 
INNER JOIN PEDI_InvoiceDetail ON ... 
0

Spróbuj następujące zapytanie:

;WITH CTE_DocTotal 
AS 
(
    SELECT SUM(Sale + VAT) AS DocTotal_1 
    FROM PEDI_InvoiceDetail 
    GROUP BY InvoiceNumber 
) 

UPDATE CTE_DocTotal 
SET DocTotal = CTE_DocTotal.DocTotal_1