我正在尝试使用this solution从数据库表中删除重复的行。但是,在我的情况下,是否将两行视为“重复”,必须检查另一个表。我的场景的完整副本将是这样的:
-- Foreign key between these tables as well as "Group" table omitted for simplicity...
DECLARE @ItemType TABLE(Id INT, Title NVARCHAR(50), GroupId INT);
DECLARE @Item TABLE(Id INT IDENTITY(1,1), ItemTypeId INT, Created DATETIME2);
INSERT INTO @ItemType (Id, Title, GroupId)
VALUES (1, 'apple', 1), (2, 'banana', 1), (3, 'beans', 2);
INSERT INTO @Item (ItemTypeId, Created)
VALUES (1, '20141201'), (2, '20140615'), (3, '20140614');
-- Note: Id's are generated automatically
WITH cte AS (
SELECT ROW_NUMBER() OVER (PARTITION BY GroupId ORDER BY Created) AS Rnk
FROM @Item AS i
JOIN @ItemType AS it ON i.ItemTypeId = it.Id
)
DELETE FROM cte
WHERE Rnk > 1;
这显然会失败,并显示以下消息:
视图或函数'cte'不可更新,因为修改会影响多个基表。
这可以在坚持优雅的cte解决方案的同时解决吗?或者这是否需要转移到基于DELETE
甚至MERGE INTO
的版本?
答案 0 :(得分:2)
您可以坚持使用CTE版本,但DELETE
必须更明确地说明要删除哪些行。只需从CTE传递@Item.Id
并根据以下内容过滤为删除的行:
WITH cte AS (
SELECT i.Id,
ROW_NUMBER() OVER (PARTITION BY GroupId ORDER BY Created) AS Rnk
FROM @Item AS i
JOIN @ItemType AS it ON i.ItemTypeId = it.Id
)
DELETE FROM @Item
WHERE Id IN (SELECT Id FROM cte WHERE Rnk > 1);