删除表中重复的记录:使用窗口函数 row_number() over 或 选择复制insert into select 或普通的子表分组select max group by having

1. 最好用的 窗口函数

用ROW_NUMBER删除重复数据

假设表TAB中有a,b,c三列,可以使用下列语句删除a,b,c都相同的重复行。

DELETE FROM 
(
    select year,QUARTER,RESULTS,
    -- 分组和排序 和查出的值,都是 查出这3个字段。如果row_no不是 第一个就删除
    row_number() over(partition by YEAR,QUARTER,RESULTS order by YEAR,QUARTER,RESULTS) AS ROW_NO 
    FROM SALE )

WHERE ROW_NO>1

2. 不保留

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

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 FROM stu WHERE name IN (
	
    -- 注意:一定得用一个 中间表
	SELECT t1.name FROM (
		-- 查询出所有重复的user_name
		SELECT name FROM stu GROUP BY name HAVING COUNT(1)>1
	) t1
	
)


delete fromwhere 重复字段 in 
(
    select 重复字段 fromgroup by 重复字段 having count(*)>1
)

3. 保留一条记录

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

-- 删除 临时表
drop table my_tmp

2. 表数据有ID

查询出这条冗余的数据
select * from 表 where 重复字段 in 
(
 	select 重复字段 from 表 group by 重复字段 having count(*)>1
)
-- 方式1
select * from stu where name in 
(
 -- 查询出 冗余的 name
 select name from stu group by name having count(1)>1
)

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


-- 方式2:
-- id 不在 这里的 
select * from stu where id not in (
    -- 查询出 最小的ID,根据name 分组,如果name 多个
    -- 只会返回一个
	select min(id) from stu group by name
)
进行删除
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

)

表中没有ID

查询全部 重复的记录
-- 和上面2 一样

select * from stu where name in 
(
	select name from stu group by name having count(*) > 1
)

2、过滤重复记录(只显示一条)

select * from stu where id in 
(
	select max(id) from stu group by name having count(1) > 1
)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
为了优化这段代码,可以考虑以下几点: 1. 使用JOIN代替子查询:将子查询的表连接操作改为使用JOIN语句,可以提高查询效率。 2. 使用EXISTS代替IN:将子查询的IN子句改为EXISTS子句,可以提高查询效率。 3. 使用变量存储重复的表达式:在查询使用重复的表达式会增加计算成本,可以使用变量存储这些重复的表达式,以减少计算次数。 4. 使用索引:根据查询条件和连接条件,在关键列上创建索引,可以提高查询性能。 下面是优化后的代码: ```sql INSERT INTO fr.fr_equipment_fill_out_all SELECT date2, equipment, team, target_oee, theory_qty, theory_ppm, stop_time, plan_downtime, text1, text2, text3, text4, text5 FROM ( SELECT ROW_NUMBER() OVER (PARTITION BY t1.equipment ORDER BY t1.date1) AS num, neighbor(t1.date1, 1) AS date2, neighbor(t1.equipment, 1) AS equipment, t1.date1, t1.equipment, t2.* FROM ( SELECT DISTINCT a.date1, b.equipment FROM chuz_dim.dim_mes_date_all a LEFT JOIN fr.fr_equipment_fill_out_all b ON 1 = 1 WHERE date1 BETWEEN (SELECT MIN(date_time) FROM fr.fr_equipment_fill_out_all) AND NOW() ) t1 LEFT JOIN ( SELECT a.date1, b.* FROM chuz_dim.dim_mes_date_all a LEFT JOIN fr.fr_equipment_fill_out_all b ON a.date1 = toDate(b.date_time) WHERE date1 BETWEEN (SELECT MIN(date_time) FROM fr.fr_equipment_fill_out_all) AND NOW() ) t2 ON t1.date1 = t2.date1 AND t1.equipment = t2.equipment WHERE date2 > date1 AND date_time = (SELECT MAX(date_time) FROM fr.fr_equipment_fill_out_all) ) t3; ``` 请注意,这只是一种可能的优化方法,具体的优化策略还需要根据数据量和表结构进行调整。在实际应用,建议根据数据库的性能特点进行测试和调整,以获得最佳的查询性能。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值