热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

面试必备:如何实现SQL语句删除重复记录且只保留一条有效记录?

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

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

首先写了一个小的例子:

一、单个字段的操作

这是数据库中的表:

23e7d4fcbccb3ea5454a589b65f3c6f6.jpeg

分组介绍

39de796efa1c9f1c9b6fff9f8ae442f7.jpeg

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

查看是否有重复的数据:

  • GROUP BY <列名序列>

  • HAVING <组条件表达式>

查询出&#xff1a;根据dname分组&#xff0c;同时满足having字句中组条件表达式&#xff08;重复次数大于1&#xff09;的那些组

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

count(*)与count&#xff08;列名&#xff09;的区别&#xff1a;

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

1、 查询全部重复的数据

1e374bb501fdecfbab6e7f10a69034c2.jpeg

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

2、删除全部重复试题

将上面的查询select改为delete&#xff08;这样会出错的&#xff09;。面试宝典&#xff1a;www.yoodb.com

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

会出现如下错误&#xff1a;[Err] 1093 - You can&#39;t specify target table &#39;dept&#39; for update in FROM clause

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

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

90ca76a7bc525335136072aa559d3163.jpeg

3、查询表中多余重复试题&#xff08;根据depno来判断&#xff0c;除了rowid最小的一个&#xff09;

a. 第一种方法&#xff1a;

0499104792c972f5c6d92893b01b1487.jpeg

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

上面这种写法正确&#xff0c;但是查询的速度太慢&#xff0c;可以试一下下面这种方法&#xff1a;

b. 第二种方法&#xff1a;

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

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

c. 补充第三种方法&#xff1a;

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

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

a. 第一种方法&#xff1a;

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. ☆第二种方法&#xff08;与上面查询的第二种方法对应&#xff0c;只是将select改为delete&#xff09;&#xff1a;

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

c. 补充第三种方法&#xff08;评论区推荐的一种方法&#xff09;&#xff1a;

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

二、多个字段的操作

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

此处只写一个&#xff0c;其他方法请仿照一个字段的写即可。

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
)

总结

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

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

  • 将*改为你需要查询出来的字段&#xff0c;不要全部查询出来

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

作者&#xff1a;千g

blog.csdn.net/n950814abc/article/details/82284838

公众号“Java精选”所发表内容注明来源的&#xff0c;版权归原出处所有&#xff08;无法查证版权的或者未注明出处的均来自网络&#xff0c;系转载&#xff0c;转载的目的在于传递更多信息&#xff0c;版权属于原作者。如有侵权&#xff0c;请联系&#xff0c;笔者会第一时间删除处理&#xff01;
最近有很多人问&#xff0c;有没有读者交流群&#xff01;加入方式很简单&#xff0c;公众号Java精选&#xff0c;回复“加群”&#xff0c;即可入群&#xff01;Java精选面试题&#xff08;微信小程序&#xff09;&#xff1a;3000&#43;道面试题&#xff0c;包含Java基础、并发、JVM、线程、MQ系列、Redis、Spring系列、Elasticsearch、Docker、K8s、Flink、Spark、架构设计等&#xff0c;在线随时刷题&#xff01;
------ 特别推荐 ------
特别推荐&#xff1a;专注分享最前沿的技术与资讯&#xff0c;为弯道超车做好准备及各种开源项目与高效率软件的公众号&#xff0c;「大咖笔记」&#xff0c;专注挖掘好东西&#xff0c;非常值得大家关注。点击下方公众号卡片关注。点击“阅读原文”&#xff0c;了解更多精彩内容&#xff01;文章有帮助的话&#xff0c;点在看&#xff0c;转发吧&#xff01;


推荐阅读
  • 在什么情况下MySQL的可重复读隔离级别会导致幻读现象? ... [详细]
  • 本文详细介绍了数据库并发控制的基本概念、重要性和具体实现方法。并发控制是确保多个事务在同时操作数据库时保持数据一致性的关键机制。文章涵盖了锁机制、多版本并发控制(MVCC)、乐观并发控制和悲观并发控制等内容。 ... [详细]
  • 本文总结了在SQL Server数据库中编写和优化存储过程的经验和技巧,旨在帮助数据库开发人员提升存储过程的性能和可维护性。 ... [详细]
  • php更新数据库字段的函数是,php更新数据库字段的函数是 ... [详细]
  • 数据类型和操作数据表2.1MySQL类型之整型2.2MySQL数据类型之浮点型2.3日期时间型DATE1支持时间:1000年1月1日~9999年12月31日DATETIME ... [详细]
  • 本文详细介绍了MySQL数据库的基础语法与核心操作,涵盖从基础概念到具体应用的多个方面。首先,文章从基础知识入手,逐步深入到创建和修改数据表的操作。接着,详细讲解了如何进行数据的插入、更新与删除。在查询部分,不仅介绍了DISTINCT和LIMIT的使用方法,还探讨了排序、过滤和通配符的应用。此外,文章还涵盖了计算字段以及多种函数的使用,包括文本处理、日期和时间处理及数值处理等。通过这些内容,读者可以全面掌握MySQL数据库的核心操作技巧。 ... [详细]
  • 通过使用Sqoop导入工具,可以精确控制并高效地将表数据的特定子集导入到HDFS中。具体而言,可以通过在导入命令中添加WHERE子句来指定所需的数据范围,从而在数据库服务器上执行相应的SQL查询,并将查询结果高效地存储到HDFS中。这种方法不仅提高了数据导入的灵活性,还确保了数据的准确性和完整性。 ... [详细]
  • MySQL Decimal 类型的最大值解析及其在数据处理中的应用艺术
    在关系型数据库中,表的设计与SQL语句的编写对性能的影响至关重要,甚至可占到90%以上。本文将重点探讨MySQL中Decimal类型的最大值及其在数据处理中的应用技巧,通过实例分析和优化建议,帮助读者深入理解并掌握这一重要知识点。 ... [详细]
  • 在使用达梦数据库时,管理员可能会遇到连接频繁中断或特定SQL语句语法错误的问题。这些问题通常源于开发人员在创建对象时的不规范操作。为了解决这些问题,建议对数据库配置进行优化,并确保所有SQL语句符合达梦数据库的标准语法。此外,定期检查和维护数据库连接参数,以及对异常日志进行详细分析,也有助于及时发现并解决问题。 ... [详细]
  • MySQL的查询执行流程涉及多个关键组件,包括连接器、查询缓存、分析器和优化器。在服务层,连接器负责建立与客户端的连接,查询缓存用于存储和检索常用查询结果,以提高性能。分析器则解析SQL语句,生成语法树,而优化器负责选择最优的查询执行计划。这一流程确保了MySQL能够高效地处理各种复杂的查询请求。 ... [详细]
  • 为了确保数据库的高效运行,本文介绍了一种方法,通过编写定时任务脚本来自动清理 `order` 表中状态为 0 或为空的无效订单记录。该脚本使用 PHP 编写,并设置时区为中国标准时间,每 10 分钟执行一次,以保持数据库的整洁和性能优化。此外,还详细介绍了如何配置定时任务以及脚本的具体实现步骤。 ... [详细]
  • 在Linux系统中避免安装MySQL的简易指南
    在Linux系统中避免安装MySQL的简易指南 ... [详细]
  • 服务器部署中的安全策略实践与优化
    服务器部署中的安全策略实践与优化 ... [详细]
  • 本文深入探讨了如何选择适合业务需求的MySQL存储引擎,详细解析了不同存储引擎的特点、适用场景及其在数据存储和管理中的优势。通过对比InnoDB、MyISAM等主流引擎,为读者提供了全面的技术指导和专业建议,帮助开发者在实际应用中做出明智的选择。 ... [详细]
  • 触发器的稳态数量分析及其应用价值
    本文对数据库中的SQL触发器进行了稳态数量的详细分析,探讨了其在实际应用中的重要价值。通过研究触发器在不同场景下的表现,揭示了其在数据完整性和业务逻辑自动化方面的关键作用。此外,还介绍了如何在Ubuntu 22.04环境下配置和使用触发器,以及在Tomcat和SQLite等平台上的具体实现方法。 ... [详细]
author-avatar
訫梦沁_245
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有