2012-07-19 58 views
36

我有下面的CTE會給我整個發票的DocTotal。更新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 

現在有了這個結果我想進入PEDI_InvoiceDetail裏的DocTotal值列。

我知道不會工作,我知道我錯過了什麼,它是什麼?

+0

我選擇了更好的性能CTE選項。 – Etienne 2012-07-19 17:57:30

回答

69

更新您對CTE將級聯到源表。

我不得不稍微猜測你的模式,但這樣的事情應該工作。

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

是CTE更新原子,如果運行concurnt查詢將相同的記錄更新兩次? – 2017-01-01 05:23:24

+0

CTE更新與正常更新完全相同。它是原子的,並將採用相同的表/行鎖。它不過是句法糖 – GarethD 2017-01-01 10:17:18

16

你並不需要一個CTE這個

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

但是,這樣做的正確方法是什麼?哪個更快?哪個更具可讀性? – Zack 2015-12-30 16:51:37

+3

@Zack SQL中的「正確性」和「可讀性」在某種程度上是主觀性和品味的。但是,某些歷史版本的SQL Server不包含CTE功能。 – podiluska 2016-01-04 09:23:32

+0

SQLite3 3.8.11.1抱怨:錯誤:「FROM」附近:語法錯誤 – 2016-03-28 12:43:06

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

嘗試以下查詢:

;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