如何筛选并删除同ItemID下ID值较小的重复行(含游标方案)
删除同一ItemID下ID较小的重复行
高效实现方案(无需游标)
游标逐行删除效率极低,尤其是数据量大时,用集合批量操作能大幅提升效率:
- 先验证待删除行
先执行查询确认目标行,避免误删:
SELECT t.ID, t.ItemID FROM YourTableName t JOIN ( SELECT ItemID, MAX(ID) AS MaxID FROM YourTableName GROUP BY ItemID HAVING COUNT(*) > 1 -- 仅处理存在重复的ItemID ) m ON t.ItemID = m.ItemID WHERE t.ID < m.MaxID;
比如你提到的ItemID=3105067,这个查询会返回ID=290120的行,完全匹配需求。
- 执行删除操作
确认结果无误后,执行删除语句:
DELETE t FROM YourTableName t JOIN ( SELECT ItemID, MAX(ID) AS MaxID FROM YourTableName GROUP BY ItemID HAVING COUNT(*) > 1 ) m ON t.ItemID = m.ItemID WHERE t.ID < m.MaxID;
为什么不推荐用游标?
游标是逐行处理逻辑,当表中数据量较大时,数据库性能会急剧下降。而集合操作基于数据集批量处理,引擎可以优化执行计划,效率提升明显。
特殊场景下的游标实现(仅作示例)
如果因业务限制必须使用游标,参考以下写法(不建议生产环境使用):
DECLARE @DeleteID INT; DECLARE DeleteCursor CURSOR FOR SELECT t.ID FROM YourTableName t JOIN ( SELECT ItemID, MAX(ID) AS MaxID FROM YourTableName GROUP BY ItemID HAVING COUNT(*) > 1 ) m ON t.ItemID = m.ItemID WHERE t.ID < m.MaxID; OPEN DeleteCursor; FETCH NEXT FROM DeleteCursor INTO @DeleteID; WHILE @@FETCH_STATUS = 0 BEGIN DELETE FROM YourTableName WHERE ID = @DeleteID; FETCH NEXT FROM DeleteCursor INTO @DeleteID; END; CLOSE DeleteCursor; DEALLOCATE DeleteCursor;
内容的提问来源于stack exchange,提问作者H4p7ic
相关产品推荐
相关产品推荐

