删除重复行同时还更新关系

时间:2013-07-22 15:45:22

标签: sql-server

我的数据设置如下:

CREATE TABLE TableA
(
    id int IDENTITY,
    name varchar(256),
    description varchar(256)
)

CREATE TABLE TableB
(
    id int IDENTITY,
    name varchar(256),
    description varchar(256)
) --unique constraint on name, description

CREATE TABLE TableA_TableB
(
    idA int,
    idB int
) --composite key referencing TableA and TableB

情况是我在TableB中有许多违反唯一约束的重复记录,并且这些重复记录在TableA_TableB中引用。所以我试图删除那些记录,这很简单(使用下面的CTE),但是更新TableA_TableB中的记录以反映这种变化的最佳方法是什么,即让TableA_TableB记录引用相同的ID TableB与每个重复项的不同ID相对应?

;WITH cte
 AS (SELECT ROW_NUMBER() OVER (PARTITION BY [Name], [Description]
                                   ORDER BY ( SELECT 0)) RN
     FROM   TableB)

DELETE FROM cte
WHERE  RN = 1

1 个答案:

答案 0 :(得分:2)

注意:将b.RowNum=1更改为b.RowNum>1

首先,您应该尝试使用ROLLBACK然后,如果没有问题,请取消注释COMMIT此脚本未经过测试):

DECLARE @UpdatedRows TABLE(ID INT PRIMARY KEY);

BEGIN TRANSACTION;

;WITH Base
AS(
    SELECT  ROW_NUMBER() OVER (PARTITION BY [Name], [Description] ORDER BY ( SELECT 0)) RowNum,
        MIN(id) OVER(PARTITION BY [Name], [Description]) AS NewID,
        ID -- Old ID
    FROM    TableB
),TableB_RowsForUpdate
AS(
    SELECT  *
    FROM    Base b
    WHERE   b.RowNum>1
)
UPDATE  target
SET IDB=b.NewID
OUTPUT  deleted.IDB INTO @UpdatedRows
FROM    TableA_TableB target
INNER JOIN TableB_RowsForUpdate b ON target.IDB=b.ID;

DELETE  b
FROM    TableB b INNER JOIN @UpdatedRows upd ON b.ID=upd.ID;

ROLLBACK;
-- COMMIT;