MYSQL 查找单个字段或者多个字段重复数据,清除重复数据

本文涉及的产品
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
RDS AI 助手,专业版
RDS MySQL DuckDB 分析主实例,基础系列 4核8GB
简介: MYSQL 查找单个字段或者多个字段重复数据,清除重复数据

前文


 

重复数据的情况分为两种:  


单个字段 数据重复  

所以该篇的内容就是包括


单个字段的重复数据查找  与 去重

多个字段的重复数据查找  与 去重


正文


 

示例  accountinfo 表数据如下:


image.png


场景一   单个字段重复数据查找 & 去重


我们要把上面这个表中 单个字段 account字段相同的数据找出来。


思路 分三步 简述:


第一步


要找出重复数据,我们首先想到的就是,既然是重复,那么 数量就是大于 1  就算是重复。 那就是 count 函数 。


因为我们要排查的是 单个 字段account ,那么就是需要按照 account 字段 维度 去分组。  那就是 group by 函数。


那么我们第一步写出来的mysql 语句是:


 SELECT account ,COUNT(account) as count FROM accountinfo GROUP BY account;


查询结果如下:


image.png


第二步


没错,如我们所想,count大于1的即是 account为 A  和 B 的数据。


那么我们稍作筛选,只把count大于1的数据的account  找出来。


第二步,利用having 拼接筛选条件,写出来的mysql 语句是:


 SELECT account FROM accountinfo GROUP BY account HAVING COUNT(account) > 1;


查询结果如下:


image.png


第三步


重复的account数据 A B 都找出来了,接下来我们只需要把account为A 和 B 的其他数据都一起查询出来。


那就是利用第二步查出来的数据做为子查询条件,使用 IN 函数。


第三步写出来的mysql 语句是:


 SELECT * FROM  accountinfo WHERE account IN
 (
 SELECT account FROM accountinfo GROUP BY account HAVING COUNT(account) > 1
 );


查询结果如下:


image.png

可以看到重复的数据都被我们筛选出来了。


那么怎么去重呢? 也就是说,把重复的数据删掉。


不,准确点应该说是,重复的数据都只留下一条即可,这才是去重。


紧接着上面,毕竟去重的前提肯定是找重,上面我们已经实现找重了,所以紧接着进行去重。


按照我们步骤三得到的图,就是我们需要删掉一条account为A的数据, 一条account为B的数据,去重结果图应该如下:


image.png


思路也分三步简述:


第一步


删掉数据,我们一般选择接住主键来删除,所以我们考虑从id入手。


再来看我们的重复数据:


image.png


如果我们想在这些重复数据里面,每个都保留一条,如 account 为 A 中 id=10 的数据,  account 为B 中 id=20 的数据 ,那么第一步我们就得把这两条数据从上面的


最终得到的数据 筛选出来,也就是按照 account分组,保留里面id最小的数据。使用 group by 和 min 函数。


所以去重我们第一步写出来的mysql 语句是:


SELECT min(id) as id from (
 SELECT * FROM  accountinfo WHERE account IN
 (
 SELECT account FROM accountinfo GROUP BY account HAVING COUNT(account) > 1
 ) 
 ) a GROUP BY a.account


查询结果如下:


image.png


第二步


想要保留的数据已经找出来了,那么接下来就是从所有的重复数据里面 删掉 不为 我们保留的数据 即可 。


那么就是找出我们需要删除的id, 使用 not in 函数。


所以去重我们第二步写出来的mysql 语句是:


SELECT t1.id FROM (
SELECT id  FROM accountinfo WHERE account IN (  SELECT account FROM accountinfo GROUP BY account HAVING COUNT(account) > 1) ) t1 
WHERE t1.id NOT IN (
SELECT min(id) AS id FROM (
 SELECT * FROM  accountinfo WHERE account IN
 (
 SELECT account FROM accountinfo GROUP BY account HAVING COUNT(account) > 1
 ) 
 ) a GROUP BY a.account
)


查询的结果为:


image.png


对这个sql语句稍作文字说明:


image.png第三步,删掉第二步找出来的数据即可,根据id删除。


所以第三步写出来的mysql语句是:


 

DELETE FROM accountinfo WHERE id IN (
SELECT t1.id FROM (
SELECT id  FROM accountinfo WHERE account IN (  SELECT account FROM accountinfo GROUP BY account HAVING COUNT(account) > 1) ) t1 
WHERE t1.id NOT IN (
SELECT min(id) AS id FROM (
 SELECT * FROM  accountinfo WHERE account IN
 (
 SELECT account FROM accountinfo GROUP BY account HAVING COUNT(account) > 1
 ) 
 ) a GROUP BY a.account
)
)

场景二  多个字段重复数据查找 & 去重



 

示例  accountinfo 表数据如下:


image.png 


想要去重,我们的首要想到的也是先把 重复数据 找出来。


现在的重复定义是, account 和 deviceId 都相同的 时候,这种数据就是重复数据(也就是上图绿色框出来的就是同时多个字段都存在重复的数据)。


思路简述:


第一步


因为有了文章上半部讲到的单个字段重复的数据查找思路,所以到这边应该更好理解了。


同样, account 和 deviceId 都相同的重复数据就是指, 这种数据存在的数量 大于 2,那么就是存在重复了。


我们还是使用到了 group by  函数 和 count 函数 和 having and  函数(因为需要同时满足两个字段条件,使用and)。


第一步写出来的mysql语句是:


SELECT account, COUNT(account), deviceId, COUNT(deviceId) 
FROM accountinfo 
GROUP BY account, deviceId 
HAVING  (COUNT(account) > 1) AND  (COUNT(deviceId) > 1) 


查询出来的结果如下图:


image.png


第二步


一样 也是把第一步里的到的关键信息 account 和 deviceId做为子查询条件,从原表里把  account 和 deviceId 同时相同的数据都查找出来。


一样 也是把第一步里的到的关键信息 account 和 deviceId做为子查询条件,从原表里把  account 和 deviceId 同时相同的数据都查找出来。


 

SELECT t.* FROM  accountinfo t, (
SELECT account, COUNT(account), deviceId, COUNT(deviceId) 
FROM accountinfo 
GROUP BY account, deviceId 
HAVING  (COUNT(account) > 1) AND  (COUNT(deviceId) > 1) 
) a 
WHERE t.account=a.account AND t.deviceId=a.deviceId 


查询结果如下图:


image.png


可以看到重复的数据都被我们筛选出来了,这些数据里面就是包含 account 和 deviceId 同时都相同的数据!


去重


第一步


思路一样,我们对于重复的数据每个只保留一条,那就是把这些涉及重复的数据每个都找出一条,也是根据id入手。


也就是在account为 C 且 deviceId 为 C333  三条重复数据里面,保留 id最小的 等于30 这一条;


account为D 且 deviceId 为 D444  二条重复数据里面,保留 id最小的 等于40 这一条.


所以第一步我们先写出来的mysql语句为:


SELECT min(id) as id FROM (
SELECT t.* FROM  accountinfo t, (
SELECT account, COUNT(account), deviceId, COUNT(deviceId) 
FROM accountinfo 
GROUP BY account, deviceId 
HAVING  (COUNT(account) > 1) AND  (COUNT(deviceId) > 1) 
) a 
WHERE t.account=a.account AND t.deviceId=a.deviceId 
)a  GROUP BY a.account,a.deviceId


查询结果如下图:


image.png


第二步


就是从涉及重复数据里面,找出除了我们需要保留的id之外的那批id, 那就是需要我们执行删除的数据id。


所以第二步我们先写出来的mysql语句为:


SELECT t.* FROM  accountinfo t, (
SELECT account, COUNT(account), deviceId, COUNT(deviceId) 
FROM accountinfo 
GROUP BY account, deviceId 
HAVING  (COUNT(account) > 1) AND  (COUNT(deviceId) > 1) 
) a 
WHERE t.account=a.account AND t.deviceId=a.deviceId 
) b   WHERE b.id
NOT IN (
SELECT min(id) as id FROM (
SELECT t.* FROM  accountinfo t, (
SELECT account, COUNT(account), deviceId, COUNT(deviceId) 
FROM accountinfo 
GROUP BY account, deviceId 
HAVING  (COUNT(account) > 1) AND  (COUNT(deviceId) > 1) 
) a 
WHERE t.account=a.account AND t.deviceId=a.deviceId 
)a  GROUP BY a.account,a.deviceId
)


查询出来的结果为:


image.png


那么最后删掉这些id的数据即可:


DELETE FROM accountinfo WHERE id in (
SELECT b.id  FROM  (  
SELECT t.* FROM accountinfo  t, (
SELECT account, COUNT(account), deviceId, COUNT(deviceId) 
FROM accountinfo 
GROUP BY account, deviceId 
HAVING  (COUNT(account) > 1) AND  (COUNT(deviceId) > 1) 
) a 
WHERE t.account=a.account AND t.deviceId=a.deviceId 
) b   WHERE b.id
NOT IN (
SELECT min(id) as id FROM (
SELECT t.* FROM  accountinfo t, (
SELECT account, COUNT(account), deviceId, COUNT(deviceId) 
FROM accountinfo 
GROUP BY account, deviceId 
HAVING  (COUNT(account) > 1) AND  (COUNT(deviceId) > 1) 
) a 
WHERE t.account=a.account AND t.deviceId=a.deviceId 
)a  GROUP BY a.account,a.deviceId
)
)



去重后结果为:


image.png


该篇就到此吧。

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
相关文章
|
10月前
|
缓存 NoSQL 关系型数据库
美团面试:MySQL有1000w数据,redis只存20w的数据,如何做 缓存 设计?
美团面试:MySQL有1000w数据,redis只存20w的数据,如何做 缓存 设计?
美团面试:MySQL有1000w数据,redis只存20w的数据,如何做 缓存 设计?
|
8月前
|
SQL 人工智能 关系型数据库
如何实现MySQL百万级数据的查询?
本文探讨了在MySQL中对百万级数据进行排序分页查询的优化策略。面对五百万条数据,传统的浅分页和深分页查询效率较低,尤其深分页因偏移量大导致性能显著下降。通过为排序字段添加索引、使用联合索引、手动回表等方法,有效提升了查询速度。最终建议根据业务需求选择合适方案:浅分页可加单列索引,深分页推荐联合索引或子查询优化,同时结合前端传递最后一条数据ID的方式实现高效翻页。
444 0
|
7月前
|
存储 关系型数据库 MySQL
在CentOS 8.x上安装Percona Xtrabackup工具备份MySQL数据步骤。
以上就是在CentOS8.x上通过Perconaxtabbackup工具对Mysql进行高效率、高可靠性、无锁定影响地实现在线快速全量及增加式数据库资料保存与恢复流程。通过以上流程可以有效地将Mysql相关资料按需求完成定期或不定期地保存与灾难恢复需求。
578 10
|
8月前
|
SQL 存储 缓存
MySQL 如何高效可靠处理持久化数据
本文详细解析了 MySQL 的 SQL 执行流程、crash-safe 机制及性能优化策略。内容涵盖连接器、分析器、优化器、执行器与存储引擎的工作原理,深入探讨 redolog 与 binlog 的两阶段提交机制,并分析日志策略、组提交、脏页刷盘等关键性能优化手段,帮助提升数据库稳定性与执行效率。
223 0
|
11月前
|
关系型数据库 MySQL Linux
在Linux环境下备份Docker中的MySQL数据并传输到其他服务器以实现数据级别的容灾
以上就是在Linux环境下备份Docker中的MySQL数据并传输到其他服务器以实现数据级别的容灾的步骤。这个过程就像是一场接力赛,数据从MySQL数据库中接力棒一样传递到备份文件,再从备份文件传递到其他服务器,最后再传递回MySQL数据库。这样,即使在灾难发生时,我们也可以快速恢复数据,保证业务的正常运行。
515 28
|
9月前
|
关系型数据库 MySQL
MySQL数据表添加字段(三种方式)
本文解析了数据表的基本概念及字段添加方法。在数据表中,字段是纵向列结构,记录为横向行数据。MySQL通过`ALTER TABLE`指令支持三种字段添加方式:1) 末尾追加字段,直接使用`ADD`语句;2) 首列插入字段,通过`FIRST`关键字实现;3) 指定位置插入字段,利用`AFTER`指定目标字段。文内结合`student`表实例详细演示了每种方法的操作步骤与结构验证,便于理解与实践。
|
Java 关系型数据库 MySQL
SpringBoot 通过集成 Flink CDC 来实时追踪 MySql 数据变动
通过详细的步骤和示例代码,您可以在 SpringBoot 项目中成功集成 Flink CDC,并实时追踪 MySQL 数据库的变动。
3168 45
|
存储 SQL 关系型数据库
【YashanDB知识库】MySQL迁移至崖山char类型数据自动补空格问题
**简介**:在MySQL迁移到崖山环境时,若字段类型为char(2),而应用存储的数据仅为'0'或'1',查询时崖山会自动补空格。原因是mysql的sql_mode可能启用了PAD_CHAR_TO_FULL_LENGTH模式,导致保留CHAR类型尾随空格。解决方法是与应用确认数据需求,可将崖山环境中的char类型改为varchar类型以规避补空格问题,适用于所有版本。
|
10月前
|
存储 SQL 缓存
mysql数据引擎有哪些
MySQL 提供了多种存储引擎,每种引擎都有其独特的特点和适用场景。以下是一些常见的 MySQL 存储引擎及其特点:
277 0
|
SQL 关系型数据库 MySQL
【YashanDB知识库】字符集latin1的MySQL中文数据如何迁移到YashanDB
本文探讨了在使用YMP 23.2.1.3迁移MySQL Server字符集为latin1的中文数据至YashanDB时出现乱码的问题。问题根源在于MySQL latin1字符集存放的是实际utf8编码的数据,而YMP尚未支持此类场景。文章提供了两种解决方法:一是通过DBeaver直接迁移表数据;二是将MySQL表数据转换为Insert语句后手动插入YashanDB。同时指出,这两种方法适合单张表迁移,多表迁移可能存在兼容性问题,建议对问题表单独处理。
【YashanDB知识库】字符集latin1的MySQL中文数据如何迁移到YashanDB

推荐镜像

更多