SQL Server删除重复记录:保留最小Id的TransactionId唯一行
解决方案:删除重复TransactionId记录,保留Id最小的行
针对你的Microsoft SQL Server表去重需求,我给你整理了两种实用且安全的方法,你可以根据实际场景选择:
方法1:使用CTE+ROW_NUMBER()函数(推荐)
这种方式逻辑清晰,还能提前预览要删除的记录,避免误操作:
WITH DuplicateRecords AS ( SELECT Id, TransactionId, -- 按TransactionId分组,每组内按Id升序编号,最小的Id会被标记为行号1 ROW_NUMBER() OVER (PARTITION BY TransactionId ORDER BY Id ASC) AS RowNum FROM [database].[dbo].[UserInAppPurchase] ) -- 删除每组中行号大于1的重复记录,只保留Id最小的那一行 DELETE FROM DuplicateRecords WHERE RowNum > 1;
安全验证步骤:
执行删除前,先把DELETE换成SELECT *,确认要删除的记录是否符合预期:
WITH DuplicateRecords AS ( SELECT Id, TransactionId, ROW_NUMBER() OVER (PARTITION BY TransactionId ORDER BY Id ASC) AS RowNum FROM [database].[dbo].[UserInAppPurchase] ) SELECT * FROM DuplicateRecords WHERE RowNum > 1;
方法2:使用DELETE结合子查询
如果你偏好更简洁的写法,可以直接通过子查询筛选出每个TransactionId对应的最小Id,再删除不在这个集合里的记录:
DELETE FROM [database].[dbo].[UserInAppPurchase] WHERE Id NOT IN ( -- 分组获取每个TransactionId的最小Id SELECT MIN(Id) FROM [database].[dbo].[UserInAppPurchase] GROUP BY TransactionId );
重要注意事项:
- 备份优先:执行删除前务必先备份表数据,防止意外:
SELECT * INTO [database].[dbo].[UserInAppPurchase_Backup] FROM [database].[dbo].[UserInAppPurchase];
- NULL值处理:如果
TransactionId存在NULL值,SQL Server会把所有NULL记录归为同一组。若需要单独处理这类情况,可以在子查询中添加WHERE TransactionId IS NOT NULL,根据业务需求调整。 - 性能优化:如果表数据量较大,建议给
TransactionId和Id字段创建联合索引,提升分组查询的效率。
内容的提问来源于stack exchange,提问作者Andreas
相关产品推荐
相关产品推荐

