Mysql查询重复数据并按条件删除重复行

在对游戏进行合区的过程中, 存在一个情况,
那就是当一个账号在两个区都存在角色的时候, 需要按照条件对重复角色进行删除,
比如以等级为条件, 只保留等级高的.


解决方案

用mysql语句, 两条就可以解决:

首先, 第一条语句

create temporary table temp as 
select user_id,max(level) as MAXID 
from user group by open_id;
这一句是将表user里面的数据按open_id进行分组, 
然后查询每组里等级最大的行的user_id,level两个字段, 
将查询结果存在一个临时表temp里面.

第二条语句

delete from user where user_id not in 
(select user_id from temp); 
将user表里,没有存入temp表的user_id字段所在行删掉.

这部分内容添加于9.2日晚———————-begin

刚刚测试发现, 上面两条命令存在一定的问题, 原因很简单,
第一条语句存入temp的user_id
并不一定就是max(level)所在行的user_id.


那么我用了另一种方式来解决, 三条命令:

1.   create temporary table temp1 as select level, user_id, open_id from user order by level;

    将user表的三项字段存入临时表temp1, 以level进行排序.

2.   create temporary table temp2 as select user_id, level, open_id from temp1 group by open_id having count(open_id) > 1;

按open_id分组, 将分组后有重复数据的组的首个数据存入临时表temp2, 
因为默认以level排序, 所以存入的是有重复项的低等级玩家id.

delete from user where user_id in (select user_id from temp2);
删除啦!

————————————————end

报错

有的小伙伴在执行第一条命令时可能会报下面的错误

ERROR 1055 (42000): Expression #1 of SELECT 
list is not in GROUP BY clause and contains nonaggregated 
column 'd1.user.user_id' which is not functionally 
dependent on columns in GROUP BY clause; 
this is incompatible with sql_mode=only_full_group_by

那是因为mysql默认的设置要求,
group By后查询的列必须存在于group by后的字段集中,
修改设置即可, 在mysql命令行执行下面语句

set @@sql_mode='
STRICT_TRANS_TABLES,
NO_ZERO_IN_DATE,
NO_ZERO_DATE,
ERROR_FOR_DIVISION_BY_ZERO,
NO_AUTO_CREATE_USER,
NO_ENGINE_SUBSTITUTION';
如果本文对你有用,可以请作者喝杯茶~
0%