牛客网MySQL题目:删除emp_no重复的记录,只保留最小的id对应的记录的解题过程与思路讲解

先看牛客网的题目:删除emp_no重复的记录,只保留最小的id对应的记录
题目用到的表结构和测试数据(因为已经有人写过这个文章,所以前面题目与他的高度相似,这是没办法,题目相同,测试用例也是一样。所以我改了一些测试用例的参数,所以与截图返回的结果不一样,希望看到这篇文章的人可以见谅。希望可以标志我的为原创!):

CREATE TABLE IF NOT EXISTS titles_test (
id int(11) not null primary key,
emp_no int(11) NOT NULL DEFAULT '',
title_name varchar(50) NOT NULL DEFAULT '',
fromdate date NOT NULL DEFAULT '',
todate date DEFAULT NULL DEFAULT '');
insert into titles_test values ('1', '12121', 'manager', '1981-01-29', '9999-01-01'),
('2', '12122', 'CEO', '1982-12-02', '9999-01-01'),
('3', '12123', 'manager', '1975-02-12', '9999-01-01'),
('4', '12124', 'manager', '1998-11-23', '9999-01-01'),
('5', '12125', 'manager', '1988-09-12', '9999-01-01'),
('6', '12126', 'CEO', '1999-02-11', '9999-01-01'),
('7', '12127', 'manager', '1999-11-13', '9999-01-01');

在这里插入图片描述

这时候,我们的表中已经有7条数据。我们发现,测试数据中,相同的数据id分别是1,2,3,5,6,7

解题思路:我们可以使用GROUP BY ,HAVING先把重复的id查找出来,SQL如下:

SELECT
	id 
FROM
	titles_test 
GROUP BY
	emp_no 
HAVING
	count( emp_no ) > 1;

我们会发现,查找的结果是
在这里插入图片描述
虽然这样子,也可以进行下一步操作,然后把重复的数据删除,最后只保留id为4,5,6,7的数据,但是这样子却与题目不相符。所以,我们需要把id值为5,6,7的重复数据查找出来,然后再去删除对应id的数据,才能满足需要,那么我们只需要加上MAX()函数即可。SQL语句如下:

SELECT
	MAX( id ) AS id 
FROM
	titles_test 
GROUP BY
	emp_no 
HAVING
	COUNT( emp_no ) > 1

结果如下:
在这里插入图片描述
最后我们使用DELTE FROM table WHERE [condition]语句即可。

这是错误执行语句
DELETE 
FROM
	titles_test 
WHERE
	id IN ( SELECT MAX( id ) AS id FROM titles_test GROUP BY emp_no HAVING COUNT( emp_no ) > 1 )

报错:1093 - You can’t specify target table ‘titles_test’ for update in FROM clause。
原因是:不能先select出同一表中的某些值,再update这个表(在同一语句中)
或者这样子去理解更好:更新这个表的同时又查询了这个表,查询这个表的同时又去更新了这个表,可以理解为死锁。mysql不支持这种更新查询同一张表的操作

因此我们需要修改一下执行语句:

这是正确的执行语句
DELETE FROM
	titles_test 
WHERE
	id IN (
	SELECT
		a.id 
	FROM
	(
		SELECT 
				max( id ) AS id 
		FROM 
			titles_test 
		GROUP BY 
			emp_no 
		HAVING 
			count( emp_no ) > 1 ) 
		AS a 
	)

这个时候,我们发现结果就是符合题目要求了。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值