MySql删除重复数据

1. 问题引入

前一段遇到MySql数据重复的问题。由于重复向同一张表导入同一批数据,导致前台展示的数据重复,唯一方便快捷的方法莫过于利用delete操作删除重复数据(已经封板发布),只保留其中一条数据。但真的是书到用时方恨少,技术也如此。当时只好在网上搜索资源,最终解决了燃眉之急。但是对找到的delete语句并不是太理解,后来抽时间自己研究了一下。现在稍微理解了一点,分享给大家,希望对大家有帮助。

2.数据准备

  • 创建表
	CREATE TABLE test_del_repetition(
	querymonth VARCHAR(6) DEFAULT NULL COMMENT '查询年月',
	province VARCHAR(15) DEFAULT NULL COMMENT '省份',
	city VARCHAR(15) DEFAULT NULL COMMENT '城市',
	population INT(10) DEFAULT 0 COMMENT '人口(万)',
	KEY pro (province) USING BTREE,
	KEY cit (city) USING BTREE,
	KEY pop (population) USING BTREE,
	KEY synthesis (province,city,population) USING BTREE
	)ENGINE=INNODB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
  • 插入数据
insert into test_del_repetition values('202107','河南省','南阳市',1002);
insert into test_del_repetition values('202107','河南省','郑州市',956);
insert into test_del_repetition values('202107','河南省','周口市',880);
insert into test_del_repetition values('202107','河南省','驻马店市',695);
insert into test_del_repetition values('202107','河南省','洛阳市',674);
insert into test_del_repetition values('202107','河南省','信阳市',640);
insert into test_del_repetition values('202107','河南省','新乡市',572);
insert into test_del_repetition values('202107','河南省','安阳市',511);
insert into test_del_repetition values('202107','河南省','濮阳市',361);

3.delete操作

经过私下测试发现造成重复数据的原因主要有两种,一种是重复导入同一批数据,造成每一条数据都存在重复现象;
另一种情况是数据处理不当,数据中个别几条数据存在重复。

3.1 情况一: 重复导入同一批数据

  • 数据模拟
#第一次插入
insert into test_del_repetition values('202107','河南省','南阳市',1002);
insert into test_del_repetition values('202107','河南省','郑州市',956);
insert into test_del_repetition values('202107','河南省','周口市',880);
insert into test_del_repetition values('202107','河南省','驻马店市',695);
insert into test_del_repetition values('202107','河南省','洛阳市',674);
insert into test_del_repetition values('202107','河南省','信阳市',640);
insert into test_del_repetition values('202107','河南省','新乡市',572);
insert into test_del_repetition values('202107','河南省','安阳市',511);
insert into test_del_repetition values('202107','河南省','濮阳市',361);
#第二次插入
insert into test_del_repetition values('202107','河南省','南阳市',1002);
insert into test_del_repetition values('202107','河南省','郑州市',956);
insert into test_del_repetition values('202107','河南省','周口市',880);
insert into test_del_repetition values('202107','河南省','驻马店市',695);
insert into test_del_repetition values('202107','河南省','洛阳市',674);
insert into test_del_repetition values('202107','河南省','信阳市',640);
insert into test_del_repetition values('202107','河南省','新乡市',572);
insert into test_del_repetition values('202107','河南省','安阳市',511);
insert into test_del_repetition values('202107','河南省','濮阳市',361);
  • 删除数据
#假设一批数据本该有m条,重复导入n次,则应该删除m*(n-1)条数据
#或者说不清楚数据本该有多少条,但根据日志得知重复导入了x次,目前总的数据量是y条,则应该删除y*((x-1)/x)条

#测试数据本应该有9条,由于重复操作2次,故应该删除掉重复的9条数据
#1.查出重复数据
select a.province from (select province,count(1) from test_del_repetition  group by province having count(1)>1)a;
#删除重复的9条数据
delete from test_del_repetition where province in (select a.province from (select province,count(1) from test_del_repetition  group by province having count(1)>1)a) limit 9;

以上这种情况只适用于同一批数据重复导入多次,此时不需要考虑主键的问题,任意一个字段都可以作为上述的条件字段,进行数据删除。
limit后面跟的就是需要删除数据的条数,也即m*(n-1)或者y*((x-1)/x)

3.2 情况二: 数据处理不当,个别数据重复

  • 数据模拟
insert into test_del_repetition values('202106','河南省','南阳市',1001);
insert into test_del_repetition values('202107','河南省','南阳市',1002);
insert into test_del_repetition values('202106','河南省','郑州市',955);
insert into test_del_repetition values('202107','河南省','郑州市',956);
insert into test_del_repetition values('202106','河南省','周口市',879);
insert into test_del_repetition values('202107','河南省','周口市',880);
insert into test_del_repetition values('202106','河南省','驻马店市',694);
insert into test_del_repetition values('202107','河南省','驻马店市',695);
insert into test_del_repetition values('202106','河南省','安阳市',510);
insert into test_del_repetition values('202107','河南省','安阳市',511);
insert into test_del_repetition values('202106','河南省','濮阳市',360);
insert into test_del_repetition values('202107','河南省','濮阳市',361);
insert into test_del_repetition values('202107','河南省','濮阳市',361);
insert into test_del_repetition values('202107','河南省','濮阳市',361);
  • 删除数据
#上面的数据只有濮阳数据存在重复,并且只有202107月的濮阳数据重复,此时就要找到表的业务主键,根据表结构可以得出业务主键是querymonth和city。

#1.获取重复数据以及数据重复次数,示例数据为 ‘202107 濮阳市 3’,也就是重复了3次,则要删除多余的2条数据
select querymonth,city,count(1) from test_del_repetition  group by querymonth,city having count(1)>1)a;
#2.删除重复数据
delete from test_del_repetition where querymonth='202107' and city ='濮阳市' limit 2;

上面这种情况针对重复的数据,不能像第一种那样整批删除。比如说重复数据有:

querymonthcitycount(1)
202107濮阳市3
202107南阳市4

濮阳重复三次,南阳重复四次,则要根据业务主键分批删除重复数据。当然这种情况也可能有更简便的方法,但是目前能力有限,希望有经验的大佬可以给出更好的答案。

本次分享到此结束,希望我的分享能给大家带来些许的便利,如果存在错误理解,也希望各位能提出来共同学习。祝大家工作顺利~

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐