我的数据设置如下:
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
答案 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;