MySQL中查询和删除重复行

1、重复行的定义

在不同的业务场景中,可能我们对重复行的定义不一样,比如以下的表记录:
在这里插入图片描述
在某些场景下,我们把name字段重复的记录称为重复行,而在另一些场景下,我们把name和address都重复的记录称为重复行,或者把name,sex,birth,address这4个字段都重复的记录称为重复行,具体可区分为两大类:单字段重复和多字段重复,无论是哪一种,我们的目的都是将重复的记录找出来,然后删除掉多余的,只保留一行,这是我们的最终目的。

2、单字段重复

这种某一个字段重复的情况很简单,我们只需要将这个字段用group by进行分组,然后用count聚合函数和having子句进行过滤就行了。

2.1、查询重复记录

还是以这张表为例:
在这里插入图片描述
现在我认为name重复的记录就是重复记录,先找出重复记录,SQL语句:

SELECT
	* 
FROM
USER 
WHERE
	NAME IN ( SELECT NAME FROM USER GROUP BY NAME HAVING count(*) > 1 );

查询结果:
在这里插入图片描述
结果是没问题的,OK,找出重复记录后的下一步是删除多余记录,只保留其中一条。

2.2、删除多余行

因为删除是按主键Id来进行删除的,修改上面的SQL语句:

SELECT
	min( id ) 
FROM
USER 
WHERE
	NAME IN ( SELECT NAME FROM USER GROUP BY NAME HAVING count(*) > 1 ) 
GROUP BY
NAME;

查询结果:
在这里插入图片描述
可以考虑用min(id)来进行筛选,保留重复记录最小id对应的记录,其余重复的删掉。

SELECT
	min( id ) 
FROM
USER 
GROUP BY
NAME;

在这里插入图片描述
刚好重复的几条记录的id都不在结果集中,那么最终的删除语句为:

DELETE 
FROM
USER 
WHERE
	id NOT IN ( SELECT tmp.mid FROM ( SELECT min( id ) mid FROM USER GROUP BY NAME ) tmp );

执行完毕后的表记录:
在这里插入图片描述
name字段重复的记录只保留下了id最小的一条,其余重复的删掉了。

3、多字段重复

先补充一下表记录:
在这里插入图片描述

3.1、查询重复记录

现在我认为name,sex和address都相同的记录才是重复的,那么先查询出来:

SELECT
	* 
FROM
USER 
WHERE
	( NAME, sex, address ) IN (
	SELECT NAME
		,
		sex,
		address 
	FROM
	USER 
	GROUP BY
		NAME,
		sex,
		address 
	HAVING
	count(*) > 1 
	);

查询结果:
在这里插入图片描述
结果没问题。

3.2、删除多余行

还是使用min(id)来筛选,先查询:

SELECT
	min( id ) 
FROM
USER 
GROUP BY
	NAME,
	sex,
	address

在这里插入图片描述
然后删除,最终语句:

DELETE 
FROM
USER 
WHERE
	id NOT IN ( SELECT tmp.mid FROM ( SELECT min( id ) mid FROM USER GROUP BY NAME, sex, address ) tmp );

执行后的表记录:
在这里插入图片描述
可以看到,name、sex、address都相同的重复记录只保留了一条,其余多的删掉了。

4、小结

重复记录的定义不同,可根据具体业务场景来进行筛选删除,无论是单字段还是多字段重复,大体思路都一样,借助min(id)或max(id)来辅助筛选删除。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值