SQL如何快速查找重复数据行_使用ROW_NUMBER进行标记删除

张开发
2026/4/10 23:26:13 15 分钟阅读

分享文章

SQL如何快速查找重复数据行_使用ROW_NUMBER进行标记删除
用 ROW_NUMBER() 标记重复行需按所有重复判断列如 name, emailPARTITION BYORDER BY 决定保留策略因多数数据库不支持 DELETE 中直接用窗口函数须借 CTE 或子查询删前必查、验外键、测锁影响。怎么用 ROW_NUMBER() 标记重复行核心是给每组相同数据分配一个序号序号 1 的就是重复行。关键在 PARTITION BY 的字段必须覆盖所有判断“重复”的列——比如你认为 name 和 email 一起相同才算重复那就要写 PARTITION BY name, email漏掉任何一个标记就失效。常见错误只按单列分区如只写 PARTITION BY email结果把不同 name 但同 email 的人全标成重复逻辑错位。ORDER BY 子句不能省即使只是写 ORDER BY (SELECT NULL) —— 某些数据库如 SQL Server要求显式指定排序字段影响哪一行被保留想留最新插入的就按时间戳降序想留主键最小的就按 id ASC别在子查询里直接删先查出来确认逻辑再套 DELETE删除重复行时为什么不能直接 DELETE 套 ROW_NUMBER()因为大多数数据库PostgreSQL、SQL Server、Oracle不支持在 DELETE 语句中直接使用窗口函数。硬写会报错ERROR: window functions are not allowed in DELETE 或类似提示。正确做法是把带 ROW_NUMBER() 的结果当临时表再对它删。MySQL 8.0 允许 CTE DELETE JOIN但 PostgreSQL 得用 USING 子句或 ctid需谨慎。PostgreSQL 推荐用 ctid 配合子查询DELETE FROM table WHERE ctid IN (SELECT ctid FROM (... ROW_NUMBER() ...) AS t WHERE rn 1)SQL Server 可用 CTEWITH dup AS (SELECT *, ROW_NUMBER() ... ) DELETE FROM dup WHERE rn 1MySQL 8.0 支持 CTE但注意CTE 必须紧跟 DELETE中间不能有其他语句ROW_NUMBER() 和 COUNT(*) OVER 选哪个如果只要识别重复比如查出所有重复记录用于人工核对COUNT(*) OVER (PARTITION BY ...) 更直白每行直接显示这组有多少条。但如果你想删重复、只留一条ROW_NUMBER() 更可控——它能明确告诉你哪条是第 1 条、哪条是第 2 条。 AI智研社 AI智研社是一个专注于人工智能领域的综合性平台

更多文章