点击上方蓝色“程序猿DD”,选择“设为星标”

回复“资源”获取独家整理的学习资料!

来源 | blog.csdn.net/n950814abc/article/details/82284838

最近在做题库系统,由于在题库中添加了重复的试题,所以需要查询出重复的试题,并且删除掉重复的试题只保留其中1条,以保证考试的时候抽不到重复的题。

首先写了一个小的例子:

一、单个字段的操作

这是数据库中的表:

分组介绍:

Select 重复字段 From 表 Group By 重复字段 Having Count(*)>1

查看是否有重复的数据:

  • GROUP BY <列名序列>

  • HAVING <组条件表达式>

查询出:根据dname分组,同时满足having字句中组条件表达式(重复次数大于1)的那些组

count(*)与count(1) 其实没有什么差别,用哪个都可以

count(*)与count(列名)的区别:

count(*)将返回表格中所有存在的行的总数包括值为null的行,然而count(列名)将返回表格中除去null以外的所有行的总数(有默认值的列也会被计入)

1. 查询全部重复的数据:

Select * From 表 Where 重复字段 In (Select 重复字段 From 表 Group By 重复字段 Having Count(*)>1)

2. 删除全部重复试题:

将上面的查询select改为delete(这样会出错的)

DELETE
FROMdept
WHEREdname IN (SELECTdnameFROMdeptGROUP BYdnameHAVINGcount(1) > 1)

会出现如下错误:[Err] 1093 - You can't specify target table 'dept' for update in FROM clause

原因是:更新这个表的同时又查询了这个表,查询这个表的同时又去更新了这个表,可以理解为死锁。mysql不支持这种更新查询同一张表的操作

解决办法:把要更新的几列数据查询出来做为一个第三方表,然后筛选更新。

3. 查询表中多余重复试题(根据depno来判断,除了rowid最小的一个)

a. 第一种方法:

SELECT*
FROMdept
WHEREdname IN (SELECTdnameFROMdeptGROUP BYdnameHAVINGCOUNT(1) > 1)
AND deptno NOT IN (SELECTMIN(deptno)FROMdeptGROUP BYdnameHAVINGCOUNT(1) > 1
)

上面这种写法正确,但是查询的速度太慢,可以试一下下面这种方法:

b. 第二种方法:

☆根据dname分组,查找出deptno最小的。然后再查找deptno不包含刚才查出来的。这样就查询出了所有的重复数据(除了deptno最小的那行)。

SELECT *
FROMdept
WHEREdeptno NOT IN (SELECTdt.minnoFROM(SELECTMIN(deptno) AS minnoFROMdeptGROUP BYdname) dt)

c. 补充第三种方法:

SELECT*
FROMtable_name AS ta
WHEREta.唯一键 <> ( SELECT max( tb.唯一键 ) FROM table_name AS tb WHERE ta.判断重复的列 = tb.判断重复的列 );

4. 删除表中多余重复试题并且只留1条:

a. 第一种方法:

DELETE
FROMdept
WHEREdname IN (SELECTt.dnameFROM(SELECTdnameFROMdeptGROUP BYdnameHAVINGcount(1) > 1) t)
AND deptno NOT IN (
SELECTdt.mindeptno
FROM(SELECTmin(deptno) AS mindeptnoFROMdeptGROUP BYdnameHAVINGcount(1) > 1) dt
)

b. ☆第二种方法(与上面查询的第二种方法对应,只是将select改为delete):

DELETE
FROMdept
WHEREdeptno NOT IN (SELECTdt.minnoFROM(SELECTMIN(deptno) AS minnoFROMdeptGROUP BYdname) dt)

c. 补充第三种方法(评论区推荐的一种方法):

DELETE
FROMtable_name AS ta
WHEREta.唯一键 <> (
SELECTt.maxid
FROM( SELECT max( tb.唯一键 ) AS maxid FROM table_name AS tb WHERE ta.判断重复的列 = tb.判断重复的列 ) t );

二、多个字段的操作:

单个字段的如果会了,多个字段也非常简单。就是将group by 的字段增加为你想要的即可。

此处只写一个,其他方法请仿照一个字段的写即可。

DELETE
FROMdept
WHERE(dname, db_source) IN (SELECTt.dname,t.db_sourceFROM(SELECTdname,db_sourceFROMdeptGROUP BYdname,db_sourceHAVINGcount(1) > 1) t)
AND deptno NOT IN (SELECTdt.mindeptnoFROM(SELECTmin(deptno) AS mindeptnoFROMdeptGROUP BYdname,db_sourceHAVINGcount(1) > 1) dt
)

总结:

其实上面的方法还有很多需要优化的地方,如果数据量太大的话,执行起来很慢,可以考虑加优化一下:

  • 在经常查询的字段上加上索引

  • 将*改为你需要查询出来的字段,不要全部查询出来

  • 小表驱动大表用IN,大表驱动小表用EXISTS。IN适合的情况是外表数据量小的情况,而不是外表数据大的情况,因为IN会遍历外表的全部数据,假设a表100条,b表10000条那么遍历次数就是100*10000次,而exists则是执行100次去判断a表中的数据是否在b表中存在,它只执行了a.length次数。至于哪一个效率高是要看情况的,因为in是在内存中比较的,而exists则是进行数据库查询操作的

往期推荐

一款 Java 开源的 Spring Boot 即时通讯 IM 聊天系统

Docker 入门终极指南:边学边用

推荐一款日志切割神器

成为最差开发者的10条建议

delete、truncate、drop的区别有哪些,该如何选择

为何从单体架构迁移到微服务这么难?

扫一扫,关注我

一起学习,一起进步

每周赠书,福利不断

深度内容

推荐加入

最近热门内容回顾   #技术人系列

面试:如何实现 MySQL 删除重复记录并且只保留一条相关推荐

  1. mysql删除重复记录并且只保留一条

    准备的测试表结构及数据 插入的数据中A,B,E存在重复数据,C没有重复记录 CREATE TABLE `tab` (   `id` int(11) NOT NULL AUTO_INCREMENT,   ...

  2. 如何实现 MySQL 删除重复记录并且只保留一条

    作者:千g blog.csdn.net/n950814abc/article/details/82284838 最近在做题库系统,由于在题库中添加了重复的试题,所以需要查询出重复的试题,并且删除掉重复 ...

  3. SQL Server 删除重复记录,只保留一条记录

    原文地址:http://blog.csdn.net/eriato/article/details/17417303 有张表格之前没有设计关键字段的唯一约束,导致有时候执行插入操作时不小心执行了多次就出 ...

  4. 最简单的删除重复记录(只保留一条)的SQL方法

    首先,新建一张表用于示例说明: # 新建一张表A create table A( id varchar(5), name varchar(5), salary float);# 插入数据(包含要去除的 ...

  5. 通过SQL 语句删除重复记录并且只保留一条记录

    这里写自定义目录标题 1 重复字段 2 查询全部重复的数据 3 删除全部重复试题 4 查询表中多余重复试题(根据 depno 来判断,除了 rowid 最小的一个) 4.1 第一种方法 4.2 第二种 ...

  6. SQL语句删除重复记录且只保留一条有效记录

    1.查找表中多余的重复记录,重复记录是根据单个字段(name)来判断 select * from lib where name in (select name from lib group by na ...

  7. mysql 删除重复记录,只保留id字段值最大的记录

    delete from tb_table where id not in (select maxid from (select max(id) as maxid from tb_table group ...

  8. mysql删除重复数据只保留一条_mysql查找删除重复数据并只保留一条实例详解

    有这样一张表,表数据及结果如下: school_id school_name total_student test_takers 1239 Abraham Lincoln High School 55 ...

  9. php去除重复的数据保留一条,mysql查找删除重复数据并只保留一条实例详解

    有这样一张表,表数据及结果如下: school_id school_name total_student test_takers 1239 Abraham Lincoln High School 55 ...

最新文章

  1. 16万辆汽车已经用上中国“车规AI第一芯”,量产还在加速
  2. Android .mk文件语法解析
  3. Struts 2常用的Ajax标签
  4. java全面的计算器代码_Java实现计算器的代码
  5. 干货!这可能是你见过最全的 Python 时间处理方法总结
  6. Python基础——数据分析考核(图形化版本)
  7. 设计一个程序实现两个任意长的整数的求和运算_深入 Python (7) Karatsuba 实现长整数乘法...
  8. 一站式机器学习平台建设实践
  9. 客座编辑:吴东亚(1972-),女,中国电子技术标准化研究院信息技术研究中心高级工程师、副主任,国家OID注册中心副主任。...
  10. C++基于TCP和UDP的socket通信
  11. Crashlytics功能集成
  12. Java读取Level-1行情dbf文件极致优化(2)
  13. [转载] Java static关键字详解
  14. 传导、辐射和谐波总结,大家共同学习
  15. VS2019提示“未能完成操作,不支持此接口”
  16. 事务里面的脏读、不可重复读、虚读/幻读
  17. SEO怎么做?SEO的具体流程是什么?
  18. PageHelper.startPage与PageHelper.offsetPage区别
  19. MySQL实现分数排名问题
  20. 解决IE禁止第三方Cookie

热门文章

  1. 在Eclipse中创建Maven多模块工程的例子
  2. linux 分析 进程cpu占用过高
  3. linux shell shift命令 参数移动 简介
  4. python3 文本文件内容去除重复行
  5. python3 多进程共享变量实现方法
  6. Windows页目录自映射方案
  7. 关于inline函数
  8. HTTP协议处理流程
  9. 申请阿里云服务器并远程登录
  10. php语言smtp类,php mailer类调用远程SMTP服务器发送邮件实现方法