2016-11-30 76 views
0

我們的SOP應用程序變得瘋狂了,現在我們的文檔管理系統中有成千上萬的重複文檔。如何更新SQL Server中的重複行,但保留原始?

SELECT 
    [INVOICE_NO], COUNT(*) 
FROM 
    [dwdata].[dbo].[INVOICES] 
GROUP BY 
    [INVOICE_NO] 
HAVING 
    COUNT(*) > 1 

產生數千行。每張發票只能存儲一次。

INVOICE_NO | COUNT(*) 
2338508  | 2 
2398800  | 3 
2273807  | 2 
2280570  | 4 

每一行都有一個DWSTOREDATETIME。例如:

SELECT 
    [INVOICE_NO], [WORKSORDER], [DWSTOREDATETIME] 
FROM 
    [dwdata].[dbo].[INVOICES] 
WHERE 
    [INVOICE_NO] = 2338508 

2338508 | 1571105 | 2015-11-16 13:52:41.910 
2338508 | 1571105 | 2015-10-27 07:50:59.970 

我想要做的就是更新WORKSORDER上重複的行只(留下的最古老的),以彌補一些諸如999999,我知道不存在。然後,我可以使用文檔管理系統刪除工作流程模塊根據此刪除。

+0

'SET WORKSORDER = ROW_NUMBER()(PARTITION BY INVOICE_NO ORDER BY DWSTOREDATETIME)'只是把氡子查詢/ CTE,然後更新。 –

回答

2

您可以使用一個CTE,那麼它很簡單:

WITH CTE AS 
(
    SELECT t.*, RN = ROW_NUMBER() OVER (PARTITION BY INVOICE_NO ORDER BY DWSTOREDATETIME ASC) 
    FROM dbo.TableName t 
) 
UPDATE CTE SET WORKSORDER = 999999 WHERE RN > 1 

如果你想看到你要更新使用SELECT * FROM CTE WHERE RN > 1

+0

我按照建議使用'SELECT * FROM CTE'對其進行了測試,並且列出了僅在數據庫中存在一次的'INVOICE_NO'? – user6888062

+0

@ user6888062:當然你需要應用與'UPDATE'相同的過濾器,對不起,我沒有包含它。所以'選擇*從CTE WHERE RN> 1'。 'RN = 1'的行是每個'INVOICE_NO'組中最老的。如果你不應用過濾器,你也可以找到沒有重複數字的組。 –

+0

顯然,我的不好。非常感謝。這似乎是我所需要的,現在正在運行! – user6888062

0

您可以更新重複的記錄,像下面的東西。如果您要多次運行update語句,則還需要在查詢中的分區子句中添加[WORKSORDER]列名稱以避免更新語句中的不必要記錄。

UPDATE A SET WORKSORDER=999999 
FROM 
(
SELECT 
    [INVOICE_NO],WORKSORDER, ROW_NUMBER() OVER(PARTITION BY INVOICE_NO ORDER BY DWSTOREDATETIME) RNO 
FROM 
    [DWDATA].[DBO].[INVOICES] 
)A 
WHERE A.RNO>1 
相關問題