逐步深入:mysql删除重复数据

一 背景知识

插入重复数据是很正常的情况,特别是在项目开发过程中,经常要不断重复地调试。通过学习delete 语法,还能回顾mysql的子查询,分组,条件查询等等知识。下面是一些先导知识:(已经懂的读者直接看第二节-删除所有重复数据内容
我们知道,where 条件不能加聚函数,如 where avg(score)>60, 即查询平均分大于60分,这个写法是错误的。所以诞生了having,并且在一个select语句中,where只能出现一次(子查询或者嵌套查询不算,因为本身他们就不是单个语句了)。group by 命令是按照字段进行分组,从而可以进行其他操作。如有不同学科,按照学科分组后,才方便查各科的平均分,最高分等等。
下面只能查询到一条数据,即所用科目中的最高分:

 	select  subject.name , subject.sore ,max(subject.sore ) as '最高分'
 	from subject
按照学科分组后,才方便查各科的平均分,如:
		select  subject.name , subject.sore ,max(subject.sore ) as '最高分'
		from subject
		group by subject.name

这样可以得到每个学科的分数和最高分。

常用的删除一条记录命令,如从student表中删除名字为王二的记录。

		delete from student
		where name = '王二';

二 简单粗暴版-删除所有重复数据

2.1 语法:

delete form 表A
where 字段A in (
		select 字段A
		from 表A
		group by 字段A
		having count(表A)>1
);

2.2实战:

student表有学生id,name,age3个字段。现在删除重复名字的学生。注意,这里会删除名字重复的所有学生。一般情况下,我们都希望保留一个。

delete form student
where name in (
		select name
		from student
		group by name
		having count(name)>1
);

三 正常版-删除所有重复数据但保留一条记录

第二节介绍了删除所有重复数据,如果是你自己来设计,想想如何实现保留一条记录呢?

前面介绍中,我们使用了in, 即删除这个区间里面的,

现在我们想保留一个,是不是需要什么机制或者手段来告诉sql,我要保留一条。

无可厚非,in里面的东西肯定会被一条一条的取出来,然后删除掉。所以在这个子查询中,我们好像也不能做点什么来保留,想想其他的吧!如日常中的查询,“我想要全部书”,“我想要全部书,除了音乐书”。

“我想要全部书” 假设等价于删除所有重复数据
“我想要全部书”等价于删除所有重复数据但保留一条记录

是不是加一个条件就好了,所以使用and,增加条件来保留一些合法记录。

delete form student
where name in (
		select name
		from student
		group by name
		having count(name)>1
)
and id !=1 ;

这样在重复记录中,id为1的记录就不会被删除了。但我们又不能提前知道哪些记录在不在重复记录中。所以还需要继续思考,哪些记录是在重复记录中,要是能通过查询出来就好了。id可以理解为过渡字段,来实现当中间人,记录一下保存的记录。
所以 id不是人定的,而是自己查到的,说干就干:

delete form student
where name in (
		select name
		from student
		group by name
		having count(name)>1
)
and id  **not in** (
		select **id**
		from student
		group by name
		having count(name)>1
)

这样我们就能查到与分组对应后的重复记录的id了,现在我们只需要在重复数据保留一条就好了。使用聚函数,max或者min等等
如:

delete form student
where name in (
		select name
		from student
		group by name
		having count(name)>1
)
and id  **not in** (
		select  min(id)
		from student
		group by name
		having count(name)>1
)

这样我们就能实现删除重复数据,并且保留一条记录。
总结成语法,格式为:

delete form 表A
where 重复字段 in (
		select 重复字段
		from student
		group by 重复字段
		having count(重复字段)>1
)
and 过渡字段 **not in** (
		select  min(过渡字段)
		from 表A
		group by 重复字段
		having count(重复字段)>1
)

猜你喜欢

转载自blog.csdn.net/qq_39463175/article/details/119683389
今日推荐