查询和删除mysql表中某个字段重复数据的几种方式

本文详细介绍了在MySQL中删除表中重复字段的三种方法:1) 使用GROUP BY和聚合函数;2) 利用NOT IN和子查询避免误删;3) 窗口函数实现高效去重。提供每种方法的关键SQL语句解析和注意事项。
摘要由CSDN通过智能技术生成

方式一 (重复一次)

在这里插入图片描述

首先查出重复的数据

SELECT
*
FROM
tbl_employee e,(
	SELECT max(id) id
	FROM tbl_employee d
	GROUP BY d.last_name 
	HAVING COUNT(1)>1 
) re_id_table 
WHERE e.id = re_id_table.id

在这里插入图片描述

删除

DELETE 
e
FROM
tbl_employee e,(
	SELECT max(id) id
	FROM tbl_employee d
	GROUP BY d.last_name 
	HAVING COUNT(1)>1 
) re_id_table 
WHERE e.id = re_id_table.id
sql几个关键点解释下:
  1. 由于mysql的SELECT中只能写GROUP BY中的有的字段(不包括聚合函数,可以设置sqlmode取消),所以可以通过聚合函数的形式(MAX(id)/MIN(id))查出非分组字段也就是id。多条记录要删除id最大的就用MAX(),id最小的就用MIN()
  2. DELETE时的语法,如果表用了别名,要在DELETE后面加上表的别名。

当然也可以使用重复一次的语句删除多次的重复纪录,就是执行多次

方式二(重复多次(不确定几次))

在这里插入图片描述

首先查出重复的数据

SELECT
*
FROM
tbl_employee e
WHERE e.id NOT IN (
	SELECT IFNULL(MIN(id),e.id)
	FROM (
		SELECT min(id) id,d.last_name
		FROM tbl_employee d
		GROUP BY d.last_name 
		HAVING COUNT(1)>1
	) as b
	WHERE e.last_name = b.last_name
)

![在这里插入图片描述](https://img-blog.csdnimg.cn/ea7fb3d4284140a2a9106711baf05677.png

删除

DELETE
e
FROM
tbl_employee e
WHERE e.id NOT IN (
	SELECT IFNULL(MIN(id),e.id)
	FROM (
		SELECT min(id) id,d.last_name
		FROM tbl_employee d
		GROUP BY d.last_name 
		HAVING COUNT(1)>1
	) as b
	WHERE e.last_name = b.last_name
)
sql几个关键点解释下:
  1. WHERE e.last_name = b.last_name 使用相关子查询将外表的数据代入内表。
  2. 为什么这么写IFNULL(MIN(id),e.id) :由于查不到数据返回N/A(Not Applicable,不适用的意思),需要使用聚合函数将其转换为null来判断。e.id就是外表的id。不重复的数据就返回自身id,(这是不删除不重复数据的关键)这样就不会删除不重复的数据了。

方式三 利用窗口函数删除多条重复纪录(mysql8.0以上版本支持窗口函数)

查询重复的数据

SELECT  *
FROM (
	SELECT ROW_NUMBER() OVER w AS row_num,last_name,id
	FROM tbl_employee  
	WINDOW w AS (PARTITION BY last_name ORDER BY id)
)t
WHERE row_num >1

删除重复数据

DELETE
FROM tbl_employee
WHERE id in (
	SELECT id
	FROM(
		SELECT *
		FROM (
			SELECT ROW_NUMBER() OVER w AS row_num,last_name,id
			FROM tbl_employee  
			WINDOW w AS (PARTITION BY last_name ORDER BY id)
		)t
	    WHERE row_num >1
	)e
)

写在最后

当然,不建议直接删除数据,可以逻辑删除,改成相应的update语句

MySQL中,如果尝试插入的数据的主键值已存在于表中(即主码重复),这通常会引发`UNIQUE KEY Violation`错误。这是因为主键约束确保了每一行数据的唯一性。解决这种情况有以下几种方法: 1. **忽略重复** (如果你确实想覆盖已有记录):可以使用`ON DUPLICATE KEY UPDATE`语句,它允许你在插入新记录时更新已存在的特定字段,而不是插入一条新的记录。 ```sql INSERT INTO table_name (primary_key_column, other_columns) VALUES ('value', 'other_value') ON DUPLICATE KEY UPDATE column_to_update = 'new_value'; ``` 2. **检查并修改数据**:在插入前,先查询是否已有该主键值,如果有则处理冲突,如删除、更新现有数据或获取一个唯一的标识符。 ```sql IF NOT EXISTS(SELECT * FROM table_name WHERE primary_key_column = 'value') THEN INSERT INTO table_name (primary_key_column, other_columns) VALUES ('value', 'other_value'); END IF; ``` 3. **设置自增策略**:如果主键是一个自动递增的整数,可以在创建表时指定`AUTO_INCREMENT`属性,这样每次插入时系统会自动提供一个唯一的值。 4. **更改为主键组合**:如果是复合主键(多个字段联合作为主键),确保所有字段的组合都是唯一的。 5. **使用唯一索引**:如果不想将某个字段设为主键,但需要保证其唯一,可以创建一个唯一索引来代替。 遇到这个问题时,根据你的业务需求选择合适的解决方案。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值