如何更新SQL Server中的重复行但保留原始行?

时间:2016-11-30 11:03:19

标签: sql-server sql-server-2014

我们的SOP应用程序变得疯狂,我们现在在文档管理系统中有数千个重复文档。

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之类的内容。然后,我可以使用文档管理系统删除工作流程模块进行删除。

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

您可以更新下面的重复记录。如果要多次运行update语句,则需要在查询中的partition子句中添加[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