前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如何删除重复数据

如何删除重复数据

作者头像
白日梦想家
发布2020-07-18 18:30:17
1.8K0
发布2020-07-18 18:30:17
举报
文章被收录于专栏:SQL实现SQL实现

当表设计不规范或者应用程序的校验不够严谨时,就容易导致业务表产生重复数据。因此,学会高效地删除重复就显得尤为重要。

今天我们就来说怎么删除有主键的重复数据。提前预告:下一篇文章会介绍如何删除没有主键的重复数据。

可以只使用单条 SQL 语句删除表中的重复数据,也可以借助于临时表来达到这个目的。使用单条 SQL 语句的 好处是操作原子性的,不需要考虑事务;而借助于中间表的方式则需要分成多条 SQL 语句才能完成删除操作,这个过程需要启用事务来保持数据一致性。

在这里,我们只介绍使用单条语句的操作。操作步骤如下:

  1. 找出有重复的数据;
  2. 在重复的数据中标记需要保留的数据;
  3. 删除重复数据里面没有被标记的数据。

由于主键的存在,可以将重复数据中的对应的主键的最大或最小的那条记录标记为保留数据。

我们来看具体的操作,有一个 emp 表,emp 的表结构如下:

代码语言:javascript
复制
CREATE TABLE `emp` ( `empno` int(11) NOT NULL, `ename` varchar(10)  DEFAULT NULL, `job` varchar(9)  DEFAULT NULL, `mgr` int(11) DEFAULT NULL, `hiredate` date DEFAULT NULL, `sal` decimal(7,2) DEFAULT NULL, `comm` decimal(7,2) DEFAULT NULL, `deptno` int(11) DEFAULT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8

表中的数据如下图所示(标红的是重复数据):

字段 ename 作为判断重复数据的依据,即两条或者两条以上的数据的 ename 字段的值相同,说明它们都是重复数据。

当存在重复数据时,只需要保留重复数据中 empno 最大的那条记录

方法一:

先通过 group by ... having 找到重复数据中要保留的数据,再通过关联操作删掉未选中的数据。

代码语言:javascript
复制
DELETE   a.* FROM  emp a   INNER JOIN     (SELECT       ename,      MAX(empno) AS empno     FROM      emp     GROUP BY ename     HAVING COUNT(*) > 1) b     ON b.ename = a.ename     AND b.empno <> a.empno ;

方法二:

做自关联,然后删除关联上的数据中 empno 较小的记录。

代码语言:javascript
复制
DELETE   a.* FROM  emp a   INNER JOIN emp b     ON b.ename = a.ename     AND a.empno < b.empno

如果存在比较多组的重复数据,且每组内的重复数据不是很多,使用方法二就比较高效。

如果重复数据非常少,使用方法二的就有可能出现性能问题,这时就应该选择方法一。

所以,应该先了解数据分布的情况,再选择合适的方法执行删数据操作。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-05-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 SQL实现 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档