【面试:sql删除重复的数据】只要存在冗余都删除。保留一条数据。数据都相同使用中间表。分组和嵌套 in not in。查出这条冗余的数据(取id最小或最大),内层分组取最小,外层不为这个最小

只要有重复,一条记录也不留

CREATE TABLE `stu` (
  `id` int(11) NOT NULL,
  `name` varchar(32) COLLATE utf8_bin DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
-- 直接这样查,会报错。要用 中间表,起别名
delete fromwhere 重复字段 in (
    select 重复字段 fromgroup by 重复字段 having count(*)>1
)

DELETE FROM stu WHERE name IN (
	
    -- 注意:一定得用一个 中间表
	SELECT t1.name FROM (
		-- 查询出所有重复的user_name
		SELECT name FROM stu GROUP BY name HAVING COUNT(1)>1
	) t1 -- 必须起别名
)

保留一条记录

1. 使用 中间表(对于:表数据都相同)

-- 创建临时表
create table my_tmp like stu

-- 插入临时表里数据,去重后。 (没有ID的情况)	
insert into my_tmp
select distinct * from stu

-- 删除原表
drop table stu;

-- 重命名 tmp 表为 stu
rename table my_tmp to stu

2. 使用分组和嵌套 in 或 not in

表中的数据: id 和 name
1	1
3	2
2	2
查询出这条冗余的数据 2种方式
查出冗余的列
  • 公式如下:
    • 注意:查询是 不需要中间表的
select * from 表 where 重复字段 in (
 	select 重复字段 from 表 group by 重复字段 having count(*)>1
)

-- 查询的记过
3	2
2	2

-- 方式1
select * from stu where name in (
 	-- 查询出 冗余的 name
 	select name from stu group by name having count(1)>1
)
并且这个冗余的列 id不为最小

-- 并且: id 不为 最小的ID
and id not in (
  -- 查询重复的 name 字段, 取最小的ID
  select min(id) name from stu group by name having count(1)>1
)

-- 结果
3	2
内层分组取最小,外层不为最小的ID
-- 方式2:
-- id 不在 这里的 
select * from stu where id not in (
    -- 查询出 最小的ID,根据name 分组,如果name 多个
    -- 只会返回一个
	select min(id) from stu group by name
)

SQL运行后
3	2
进行删除
方式1:上面的结果 使用中间表删除
  • max(id) 删除,id最大的
DELETE FROM stu  WHERE id in  (

	SELECT id FROM (
		-- 放上面的SQL
	) t -- 必须用中间表,并且起别名
)

		-- 放上面的SQL
		select * from stu where id not in (
				-- 查询出 最小的ID,根据name 分组,如果name 多个
				-- 只会返回一个
			select min(id) from stu group by name
		)
方式2:内层查重复的最小的id,外层不为这个id
delete from stu where id not in ( -- 删除ID,不在这里面
	-- 包一层中间表
	select t.id from (
        	
			select min(id) id from stu group by name -- 根据name分组,取出最小的 id
        
		) t -- 起别名为 t
)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值