如何删除表中重复记录?
2010-04-16 13:26
218 查看
最近项目中遇到了一个需求,即“如何删除表中重复记录,使得所有重复的记录都只保留一行?”。在Google了半个小时之后,发现居然没有一个是正常可用的,于是乎只好自己动手写了一个。因为即便是Grails提供了很好的GORM,但是使用SQL仍然不可能完全避免,因此把它共享出来,也符合咱们网站的“共享开发经验”的宗旨。
具体的分析就不多说了,这里面主要是SQL的功夫,在此就直接列出解法,实验是在MySQL上做的,实验用的表结构是(id, first_name, last_name, parent)。
基础语句,列出重复记录:
第一种做法,使用not in:
上面的语句的意思应该非常直白了,简直就是大白话。可问题是not in的效率并不是特别高,因此这就有了第二种解法,使用外联结+is null + exists:
对于有主键或有唯一性约束的表,以上解法应该足够了。但有时候如果没有主键怎么办,虽然这一点似乎有点不可思议,但实际总会遇到,尤其在表不是你设计的时候。这时,只好采用一个稍微有点“恶趣味”的做法:把distinct的结果放到另一张表中,drop掉原来的表,再把那张表重命名:
以上就是基本的解决方案,但在实际中可能情况比较复杂,尤其是在有外键关联的时候,可能就有些问题了。但话说回来,既然决定要“删除”记录,那么在作出这个决策的时候,应该就已经考虑过外键的情形了吧
具体的分析就不多说了,这里面主要是SQL的功夫,在此就直接列出解法,实验是在MySQL上做的,实验用的表结构是(id, first_name, last_name, parent)。
基础语句,列出重复记录:
select * from db1.person group by first_name,last_name,parent having count(*)>1
第一种做法,使用not in:
delete from db1.person where exists( select * from ( select a.id aid, b.id bid from db1.person a left outer join ((select max(id) id from db1.person group by first_name, last_name, parent having count(id)>1) union (select id from db1.person group by first_name, last_name, parent having count(id)=1)) b on a.id= b.id ) tmp where aid= id and bid is null )
上面的语句的意思应该非常直白了,简直就是大白话。可问题是not in的效率并不是特别高,因此这就有了第二种解法,使用外联结+is null + exists:
delete from db1.person where exists( select * from ( select a.id aid, b.id bid from db1.person a left outer join ((select max(id) id from db1.person group by first_name, last_name, parent having count(id)>1) union (select id from db1.person group by first_name, last_name, parent having count(id)=1)) b on a.id= b.id ) tmp where aid= id and bid is null )
对于有主键或有唯一性约束的表,以上解法应该足够了。但有时候如果没有主键怎么办,虽然这一点似乎有点不可思议,但实际总会遇到,尤其在表不是你设计的时候。这时,只好采用一个稍微有点“恶趣味”的做法:把distinct的结果放到另一张表中,drop掉原来的表,再把那张表重命名:
create table newperson select distinct * from person; drop table db1.person; ALTER TABLE `db1`.`newperson` RENAME TO `db1`.`person`;
以上就是基本的解决方案,但在实际中可能情况比较复杂,尤其是在有外键关联的时候,可能就有些问题了。但话说回来,既然决定要“删除”记录,那么在作出这个决策的时候,应该就已经考虑过外键的情形了吧
相关文章推荐
- 四种方法教你如何用SQL语句删除重复记录
- 如何删除表中的重复记录?
- 如何删除表中的重复记录?
- 如何使用SQL删除某个字段重复的记录,保留其中一条
- sql server 2005 如何删除前几条记录或重复记录
- 如何按字段删除重复记录
- 如何查出同一张表中字段值重复的记录,或者删除重复的记录
- mysql如何删除重复记录
- 如何快速删除Access指定字段的重复记录
- 在Oracle中如何利用Rowid查找和删除表中的重复记录
- 在Oracle中如何利用Rowid查找和删除表中的重复记录(转)
- 数据库表中有重复记录,如何删除这些重复记录保留ID最大的一个信息
- 如何删除数据库中重复的记录
- 如何删除一张表的重复记录
- 在Oracle中如何利用Rowid查找和删除表中的重复记录
- 如何删除数据库中重复的记录
- Oracle如何查找、删除表中重复的记录
- 如何删除数据表中重复的记录
- 如何删除重复记录,并且剩下一条?
- 在Oracle中如何利用Rowid查找和删除表中的重复记录