mysql根据多个字段删除重复记录只保留某字段最大值

目录

问题

目标 

解决思路

具体实现

注意事项


问题

   维护的一个系统之前由于数据录入时没有加重复判断导致库中很多记录重复的情况。

目标 

   只保留重复记录中某字段值最大的一条,其余删除。

解决思路

   首先将word和level完全相同的记录只保留id最大的记录,其次再保留相同word中level最大的记录。

具体实现

  表记录如下,需求是要将表中所有word重复的记录排重,只保留level最大的记录,其余删除。

                                                               filter_word表

idwordlevel
1AA10
2BB5
3CC3
4AA10
5AA9
6CC3
7BB7
8BB8
9DD5
10DD10

步骤1:删掉表中完全相同的记录,只保留ID最大的一条。执行语句如下:

##查询完全相同的记录中,保留最大id的记录其余删除(每组重复记录中可能有多条)
delete from filter_word
       where id in(select id from(
								select id from filter_word a 
												where (a.word,a.level) in (
												   select * from(
														          select word,level from 
                                                                  filter_word group by 
                                                                  word,level 
                                                                  having count(*)>1
                                                                 ) YY
                                                ) order by word desc
								 ) II
				    ) 
			   and id not in (
                              select mid from(
			                                 select max(id) mid from (
												select * from filter_word
												where id in(
													select id from filter_word a 
													where (a.word,a.level) in(
														select * from(
																      select word,level 
                                                                      from filter_word
                                                                      group by word,level 
                                                                      having count(*)>1 
														) ZZ
													)
											    )		
										      ) SS group by SS.word
											) TT
					          )
			    order by word desc;	

步骤2:到这一步,表中已经没有完全相同的表记录了,然后再将word相同的表记录中,保留level最大的记录,其余删除。执行语句如下:

##查询word相同的记录中,保留最大level的记录其余删除(每组重复记录中可能有多条)
delete from filter_word 
            where id in(
                        select id from(
                                   select id from filter_word a 
								   where a.word in (
                                                    select * from(
															 select word from filter_word  
															 group by word having 
                                                             count(*)>1 
														     ) as YY 
												   ) 
									) II
					   )  
			and id not in( 
					      select id from(
										  select id from filter_word a inner join 
										  (
											select word,groupId,max(level) level from 
                                            filter_word group by word having count(*) > 1
										  )b 
										  on a.word=b.word 
										  and a.level=b.level  
										) WW
					     ) 
            order by word desc;	

注意事项

  • 以上为直接执行了delete语句,这样是有风险的,实际是先将delete换成select语句执行确认没有问题再执行delete。
  • 在此过程中,参考了很多up写的查询语句,发现如果直接执行第二条语句是无法达到预期结果的,因此先将完全相同的记录过滤掉再去根据level过滤。
  • delete语句执行时遇到报错:You can‘t specify target table for update in FROM clause。原因在于不能在同一语句中,先select出同一表中的某些值,再update这个表。必须将select 的结果再通过一个中间表 select多一次并将为其命名避免该错误。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值