mysql数据库删除重复的数据保留一条

mysql数据库删除重复的数据保留一条1 问题引入假设一个场景 一张用户表 包含 3 个字段 id identity id name 现在身份证号 identity id 和姓名 name 有很多重复的数据 需要删除只保留一条有效数据 2 模拟环境 1 等入 mysql 数据库 创建一个单独的测试数据库 mysql exercisecrea exercisechar 2 创建用户表 us

1.问题引入

假设一个场景,一张用户表,包含3个字段。id,identity_id,name。现在身份证号identity_id和姓名name有很多重复的数据,需要删除只保留一条有效数据。

2.模拟环境

  • 1.登入mysql数据库,创建一个单独的测试数据库mysql_exercise
create database mysql_exercise charset utf8; 
  • 2.创建用户表users
create table users( id int auto_increment primary key, identity_id varchar(20), name varchar(20) not null ); 

在这里插入图片描述

  • 3.插入测试数据
insert into users values(0,'','张三'), (0,'','张三'), (0,'X','李四'), (0,'X','李四'), (0,'','王五'), (0,'','王五'), (0,'','赵六'); 
  • 4.解决思路
    (1)根据身份证号和name进行分组;
    (2)取出分组后的最大id(或最小id);
    (3)删除除最大(或最小)id以外的其他字段;






  • 5.第一次尝试(失败!!!)
delete from users where id not in (select max(id) from users group by identity_id,name); 

报错:

1093 (HY000): You can't specify target table 'users' for update in FROM clause 

在这里插入图片描述
因为在MYSQL里,不能先select一个表的记录,再按此条件进行更新和删除同一个表的记录。
解决办法是,将select得到的结果,再通过中间表select一遍,这样就规避了错误,
这个问题只出现于mysql,mssql和oracle不会出现此问题。






所以我们可以先将括号里面的sql语句先拿出来,先查到最大(或最小)id。

select max_id from (select max(id) as max_id from users group by identity_id,name); 

接着,又报错了!!!

ERROR 1248 (42000): Every derived table must have its own alias 

意思是说:提示说每一个衍生出来的表,必须要有自己的别名!

执行子查询的时候,外层查询会将内层的查询当做一张表来处理,所以我们需要给内层的查询加上别名
在这里插入图片描述
继续更正:
给查询到的最大(或最小id)结果当做一张新的表,起别名t,并查询t.mix_id






select t.max_id from (select max(id) as max_id from users group by identity_id,name) as t; 
  • 6.第二次尝试(成功!!!)
delete from users where id not in ( select t.max_id from (select max(id) as max_id from users group by identity_id,name) as t ); 

3.知识拓展一:更新数据

其他场景应用:要将用户表user_info里名字(name)为空字符串(“”)的用户的状态(status)改成”0″

update user_info set status='0' where user_id in (select user_id from user_info where name='') 

同样报了如下错误:

You can’t specify target table ‘user_info’ for update in FROM clause

update user_info set status='0' where user_id in (select user_id from (select user_id from user_info where name = '') t1); 

下面这种也可,细微差别,别名可带as可不带,t1.user_id 直接和内层的user_id对应也可以。

update user_info set status='0' where user_id in (select t1.user_id from (select user_id from user_info where name='') as t1); 

3.1 分步骤解析

(1)将以下查询结果作为中间表:

select user_id from user_info where name=''; 

(2)再查询一遍中间表作为结果集:

select user_id from (select user_id from user_info where name='') as t; 

(3)更新数据

update user_info set status='0' where user_id in (select user_id from (select user_id from user_info where name='') as t1); 

4.拓展练习:删除重复数据

编写一个 SQL 查询,来删除 Person 表中所有重复的电子邮箱,重复的邮箱里只保留 Id 最小 的那个。

+----+------------------+ | Id | Email | +----+------------------+ | 1 | john@example.com | | 2 | bob@example.com | | 3 | john@example.com | +----+------------------+ 
+----+------------------+ | Id | Email | +----+------------------+ | 1 | john@example.com | | 2 | bob@example.com | +----+------------------+ 
  • 解答一:
delete from Person where Id not in ( select t.min_id from ( select min(Id) as min_id from Person group by Email ) as t ); 
  • 解答二:
delete p1 from Person as p1,Person as p2 where p1.Email=p2.Email and p1.Id > p2.Id; 
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/219414.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月17日 下午10:36
下一篇 2026年3月17日 下午10:36


相关推荐

  • java集合系列——List集合之Vector介绍(四)

    Vector 类可以实现可增长的对象数组。与数组一样,它包含可以使用整数索引进行访问的组件。但是,Vector 的大小可以根据需要增大或缩小,以适应创建 Vector 后进行添加或移除项的操作。Vector 是同步的,可用于多线程。

    2022年2月26日
    45
  • 封装 继承 多态理解

    封装 继承 多态理解一 封装 1 定义封装 将类的某些信息隐藏在类内部 private 不允许外部程序直接访问 而是通过该类提供的公共属性 public 来实现对隐藏信息的操作和访问快捷键 prop TABpropfull TAB2 封装的好处 1 隐藏类的实现细节 2 只能通过规定属性访问数据 3 方便加入控制语句 4 方便修改实现二 继承 2 1 定义继承 一个类具有另一个类的属性和方法 这个类叫子类 派生类 另一个类叫父类 基类 超类 继承的关键符号 冒号

    2026年3月17日
    2
  • IDEA全局查找快捷键不管用(不起作用、没反应)[通俗易懂]

    IDEA全局查找快捷键不管用(不起作用、没反应)[通俗易懂]这种情况一般都是输入法快捷键冲突请参照博客https://blog.csdn.net/weixin_44018093/article/details/91542244进行修复

    2022年6月17日
    94
  • c语言system返回信息,理解c语言system函数的返回值

    c语言system返回信息,理解c语言system函数的返回值作者:新浪微博(@NP等不等于P)计算机学习微信公众号(jsj_xx)c语言中的system函数可以说是程序执行时的一道重生之门,其重生妙效犹如我们之前《透析硬链接和软链接的区别》一文中的软链接文件。然而,system函数也带来了判断返回值的烦恼!本文分享我们对system函数的返回值的理解,希望对c语言学习者有所帮助(如有错误,还望指正,谢谢)。先给出我们理解的system函数执行原理:fork…

    2026年1月17日
    6
  • git设置ssh key(git ssh配置)

    gitclone支持https和git(即ssh)两种方式下载源码:当使用git方式下载时,如果没有配置过sshkey,则会有如下错误提示:下面就介绍一下如何配置git的sshkey,以便我们可以用git方式下载源码。首先用如下命令(如未特别说明,所有命令均默认在GitBash工具下执行)检查一下用户名和邮箱是否配置(github支持我们用用户名或邮箱登录):git

    2022年4月12日
    54
  • 使用sortablejs拖拽列表排序

    使用sortablejs拖拽列表排序sortablejs 版本 1 14 0 框架 vue UI elementimpor sortablejs 引入开始使用 我的接口 请求表格数据 fetchData getUser then res gt this list res data data this total res data count this nextTick gt 表格渲染完成 调用拖拽排序

    2026年3月19日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号