背景

程序bug或则其他原因造成的数据重复写入数据库,造成数据冗余,修正bug后,需要将数据库中正常的数据保留,重复的数据删除

重复的表有多张,单表数据在30W-90W之间不等,想到的一种方法是使用去重脚本,脚本很简单,就是连接数据库,查出来重复数据,循环删除。但是由于每次去重查询重复数据都要进行很多次的比对,程序执行效率很低。下面介绍下从数据库直接通过sql实现

举例

user表中 有id和name属性
具体数据如下
id name
1 aa
2 bb
3 aa
4 bb
5 dd

查询可以去除的数据有哪些

select  name,count(1) from user group by name having count(1) >1

查询出来的结果分别是aa、bb各有2次,如果是删除所有重复的数据就可以直接删除了

delete from user where name in(select  name from user group by name having count(1) >1)

可实际执行的时候并不会这样,mysql不支持同一张表同时进行查询和更新操作,会报错如下

You can't specify target table 'student' for update in FROM clause

如何解决呢,将查询结果作为另外一张临时表即可,删除所有重复数据的sql如下

delete from user where name in (select t.name from (select  name from user group by name having count(1) >1)  t)

删除表中数据,相同的保留一条

首先筛选出需要保留的数据的id

select min(id) as id from user group by name 

删除数据

delect from user where id not in (select t.id from (select min(id) as id from user group by name) t)