oracle某个字段有重复数据,如何删除多余数据只保留1条

哎,跟你说个事儿,前年我在上海做项目的时候,Oracle数据库里遇到重复数据真头疼。
你说的这SQL语句,我当年可真是用得溜。

先说那个找重复的SQL,对吧。
我们那个系统里,有个表叫customers,里面有个customer_id字段老是重复。
我就用你说的这SQL:
sql SELECT customer_id, COUNT() FROM customers GROUP BY customer_id HAVING COUNT() > 1 ;
跑出来一看,嚯,有3 0多条重复记录。
这帮用户瞎操作,填了同一个customer_id。

然后要删掉这些重复的,只留一个。
你说的这个方法我也用过:
sql DELETE FROM customers WHERE rowid NOT IN ( SELECT MIN(rowid) FROM customers GROUP BY customer_id );
这个我用了两次。
第一次删的是customer_id重复的,只留最小的rowid。
删完之后,又发现还有其他字段重复的。
比如email也重复。
这时候我就得再加个字段:
sql SELECT customer_id, email, COUNT() FROM customers GROUP BY customer_id, email HAVING COUNT() > 1 ;
又跑出来一堆。
删的时候,SQL也跟着变:
sql DELETE FROM customers WHERE rowid NOT IN ( SELECT MIN(rowid) FROM customers GROUP BY customer_id, email );
这个方法确实好用,特别是只留最小的rowid。
不过有时候我们老板说,干脆全删了,不管哪个rowid。
这时候我就把SQL改成:
sql DELETE FROM customers WHERE rowid NOT IN ( SELECT MIN(rowid) FROM customers GROUP BY customer_id, email HAVING COUNT() > 1 );
你看,这SQL改起来还挺灵活的。
关键是理解那个GROUP BY和HAVING COUNT() > 1 是怎么找重复的,然后MIN(rowid)是怎么选留下来的。

哦对了,还有个坑。
你写这个DELETE语句的时候,千万注意表有没有索引。
我们那个customers表,customer_id和email都有索引,删起来就快。
要是没有索引,那真得跑一整天。
我记得有一次忘了给email加索引,结果删了三个小时,把我急得满头大汗。

所以你看,这事儿吧,光会写SQL还不够,还得知道数据库底层是怎么运行的。
你那个方法是对的,不过实际用的时候要多注意这些细节。

sql server 表中重复数据只留一条

上周有个客人问我SQL Server怎么处理表里的重复数据,我给他捋了个流程,他听完说还挺清晰的。

你这样操作确实没问题,步骤挺完整的。
我之前在2 02 3 年处理过一个项目,就是用类似的方法,不过他们当时用的是AdventureWorks数据库,处理的是产品表的数据。

备份这一步,我特别强调,因为有一次我自己踩坑了,以为测试环境没事,结果手滑删了数据,最后花了半天找备份恢复。
所以这步真的不能省,而且备份完最好再验证下备份文件。

查找重复数据用GROUP BY和HAVING COUNT() > 1 肯定行,不过他们公司有个小技巧,会先用WITH CTE把重复数据都标记出来,这样逻辑更直观。
比如:
sql WITH DuplicateCTE AS ( SELECT Sp_no, Oid, ROW_NUMBER() OVER (PARTITION BY Sp_no ORDER BY Oid) AS RowNum FROM YourTableName ) DELETE FROM DuplicateCTE WHERE RowNum > 1 ;
这个方法的好处是直接用ROW_NUMBER()分了组,然后直接删掉每组里多余的记录。
不过这个语法要求SQL Server 2 01 2 以上版本,早期版本可能要绕点路。

你说的通过查最小Oid再删,这个逻辑也对,就是步骤稍微多一点点。
关键是最后一定要用ROLLBACK TRANSACTION测试一下,确保删除操作没错再提交。
我在2 02 2 年给某个客户调试时,因为提交前没测试,结果删多了还得半夜加急恢复。

整体流程没问题,执行的时候注意几个点: 1 . 表数据量大的时候,建个索引能加快查询速度,特别是Sp_no和Oid字段 2 . 如果表关联了其他表,删数据前要考虑级联影响 3 . 备份文件别放同一个盘,最好物理隔离
反正你这样操作是没问题的,客户那边用着放心就好。

如何去掉数据库重复记录并且只保留一条记录

1 、查找表中多余的重复记录,重复记录是根据单个字段(peopleId)来判断: sql select from people where peopleId in ( select peopleId from people group by peopleId having count(peopleId) > 1 )
2 、删除表中多余的重复记录,重复记录是根据单个字段(peopleId)来判断,只留有rowid最小的记录: sql delete from people where peopleId in ( select peopleId from people group by peopleId having count(peopleId) > 1 ) and rowid not in ( select min(rowid) from people group by peopleId having count(peopleId) > 1 )
3 、查找表中多余的重复记录(多个字段): sql select from vitae where (peopleId, seq) in ( select peopleId, seq from vitae group by peopleId, seq having count() > 1 )
4 、删除表中多余的重复记录(多个字段),只留有rowid最小的记录: sql delete from vitae where (peopleId, seq) in ( select peopleId, seq from vitae group by peopleId, seq having count() > 1 ) and rowid not in ( select min(rowid) from vitae group by peopleId, seq having count() > 1 )
5 、查找表中多余的重复记录(多个字段),不包含rowid最小的记录: sql select from vitae where (peopleId, seq) in ( select peopleId, seq from vitae group by peopleId, seq having count() > 1 ) and rowid not in ( select min(rowid) from vitae group by peopleId, seq having count() > 1 )
你自己看。