mysql数据库删除重复数据只保留一条方法实例

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,'620616199409206512','张三'),
						(0,'620616199409206512','张三'),
						(0,'62062619930920651X','李四'),
						(0,'62062619930920651X','李四'),
						(0,'620622199101206211','王五'),
						(0,'620622199101206211','王五'),
						(0,'322235199909116233','赵六');

可以多执行几次,生成较多重复数据。

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;

可以成功查到最大(或最小)id了,如下图:

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
		);

执行结果:

成功将重复的数据删除,只保留了最后一次增加的记录。同理也可以保留第一次添加的记录(即删除每个分组里面除最小id以外的其他条记录)

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

因为在MYSQL里,不能先select一个表的记录,再按此条件进行更新和删除同一个表的记录,解决办法是,将select得到的结果,再通过中间表select一遍,这样就规避了错误。
以下两种均可!!!

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 是这个表的主键。

例如,在运行你的查询语句之后,上面的 Person 表应返回以下几行:

+----+------------------+
| 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;

总结

到此这篇关于mysql数据库删除重复数据的方法只保留一条的文章就介绍到这了,更多相关mysql删除重复数据内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • MySQL数据库中删除重复记录的方法总结[推荐]

    表结构: mysql> desc demo; +-------+------------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------+------------------+------+-----+---------+----------------+ | id | int(11) unsigned | NO | PRI | NULL

  • mysql删除重复行的实现方法

    表relation create table relation( id int primary key auto_increment, userId int not null, fanId int not null ); 插入几条数据 insert into relation(userId,fanId) values(1,1) ,(1,1) ,(1,1), (2,2),(2,2) ,(3,3),(3,3); 表中的数据 id userId fanId 1 1 1 2 1 1 3 1 1 4 2

  • shell脚本操作mysql数据库删除重复的数据

    由于之前的业务,造成数据库上产生了脏数据,写个脚本删除重复的数据.由于是开发测试环境,所以选择任意删除相同uid中的一条.由于每次执行只删除重复数据的一条,需要重复执行,如果本轮没有数据被删就OK #!/bin/sh # delete all company's duplicate uid MYSQL_BIN_PATH=/data/mysql/server/mysql_3306/bin MYSQL_SOCK_PATH=/data/mysql/server/mysql_3306/tmp DBUSE

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

    有这样一张表,表数据及结果如下: school_id school_name total_student test_takers 1239 Abraham Lincoln High School 55 50 1240 Abraham Lincoln High School 70 35 1241 Acalanes High School 120 89 1242 Academy Of The Canyons 30 30 1243 Agoura High School 89 40 1244 Agour

  • MySQL查询重复数据(删除重复数据保留id最小的一条为唯一数据)

    开发背景: 最近在做一个批量数据导入到MySQL数据库的功能,从批量导入就可以知道,这样的数据在插入数据库之前是不会进行重复判断的,因此只有在全部数据导入进去以后在执行一条语句进行删除,保证数据唯一性. 下面话不多说了,来一起看看详细的介绍吧 实战: 表结构如下图所示: 表明:brand 操作: 使用SQL语句查询重复的数据有哪些: SELECT * from brand WHERE brandName IN( select brandName from brand GROUP BY brand

  • mysql删除表中某一字段重复的记录

    比如,表:event(id int(10) auto_increment primary key,                 sid int(10)not null,                 detail text) 我想删除表event中sid重复的记录,请问有没有这样SQL语句?或是通过其它方法? 复制代码 代码如下: delete from event as e  where id != (select min(id) from event where sid=e.sid);

  • mysql删除重复记录语句的方法

    例如: id name value 1 a pp 2 a pp 3 b iii 4 b pp 5 b pp 6 c pp 7 c pp 8 c iii id是主键 要求得到这样的结果 id name value 1 a pp 3 b iii 4 b pp 6 c pp 8 c iii 方法1 delete YourTable where [id] not in ( select max([id]) from YourTable group by (name + value)) 方法2 delet

  • MySQL中查询、删除重复记录的方法大全

    前言 本文主要给大家介绍了关于MySQL中查询.删除重复记录的方法,分享出来供大家参考学习,下面来看看详细的介绍: 查找所有重复标题的记录: select title,count(*) as count from user_table group by title having count>1; SELECT * FROM t_info a WHERE ((SELECT COUNT(*) FROM t_info WHERE Title = a.Title) > 1) ORDER BY Titl

  • mysql查找删除表中重复数据方法总结

    在数据库表里,我们有时候会保存了很多重复的数据,这些重复的数据浪费资源,我们要将其删除掉,应该怎么处理呢?下面来看一下. 先看下我们的表数据,有一些数据是重复的. 要查找重复数据,我们可以使用mysql里的having语句,如图. 执行这个语句后,我们可以看到现在的结果里显示的就是表中重复数据的字段. 要删除这些重复的数据,我们找出这些数据的ID,在select语句里,添加id字段,使用max函数,可以得到重复数据最后面的id. 执行结果如图,得到重复数据的id为8和9. 这样我们就可以使用de

  • MySQL 删除数据库中重复数据方法小结

    刚开始,根据我的想法,这个很简单嘛,上sql语句 delete from zqzrdp where tel in (select min(dpxx_id) from zqzrdp group by tel having count(tel)>1); 执行,报错!!~!~ 异常意为:你不能指定目标表的更新在FROM子句.傻了,MySQL 这样写,不行,让人郁闷. 难倒只能分步操作,蛋疼 以下是网友写的,同样是坑爹的代码,我机器上运行不了. 1. 查询需要删除的记录,会保留一条记录. select

随机推荐