2016-11-30 45 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 
相关问题