今天查故障发现,有一个报名表竟然数据重复了,理论上一个活动中,一个手机号只会有一条记录的,我现在查了下竟然有多条记录,肯定是并发没有防住,早知道加唯一索引,早知道加redis并发拦截,但是已经来不及,那么现在需要修复数据怎么修复呢?怎样的sql可以删除多余的记录呢?
下面有两个解决方案,目前我使用的有如下两个方案。假设我的表结构如下
表名:t_gd_wx_activity
字段:actionid(主键)、phone、activity_type
方案1、多次删除方法
这个方案用于每条记录如果所有字段都一模一样(比较通用,正常肯定主键肯定不一样的),就采取这个方案,但是这个方案需要执行多次,执行到没有重复数据为止。
delete from T_GD_WX_ACTIVITY t1 where (t1.PHONE, t1.ACTIVITY_TYPE) in
(select PHONE, ACTIVITY_TYPE from T_GD_WX_ACTIVITY WHERE ACTIVITY_TYPE = '00000822' group by PHONE, ACTIVITY_TYPE having count(*) > 1)
and t1.rowid in (select min(rowid) from T_GD_WX_ACTIVITY WHERE ACTIVITY_TYPE = '00000822' group by PHONE, ACTIVITY_TYPE having count(*) > 1)
and t1.activity_type = '00000822';
方案2、一次删除方法
如果我们的记录中有别的字段不一样,比如上面的例子actionid。那么就可以用下面的方法一次性全部删除。
delete from t_gd_wx_activity w
where w.activity_type='00000822'
and w.actionid not in (select min(actionid) as id from t_gd_wx_activity a
where a.activity_type='00000822' group by a.phone );
总结
正常用方案2,但是如果所有字段一模一样,得采用方案1.
好像发现,把方案2的actionid改为rowid,更加通用
delete from t_gd_wx_activity w
where w.activity_type='00000822'
and w.rowid not in (select min(rowid) as id from t_gd_wx_activity a
where a.activity_type='00000822' group by a.phone );