mysql重命名已重名用户昵称

公司用的Sequel Pro 不支持create function.

本来会有个好用的随机数产生函数

delimiter $
CREATEFUNCTIONrandom_str(nint)RETURNSvarchar(255)
begin
declarechars_strvarchar(100)
default"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
declarereturn_strvarchar(255)default"";
declareiintdefault0;
while i < n do
setreturn_str=concat(return_str,substring(chars_str,floor(1+rand()*52),1));
seti= i+1;
endwhile;
returnreturn_str;
end$$
delimiter ;

然后并写不了,找到了一个好方法就是用 md5()+ right
最后sql为

update PN_UserTest as u1 inner join PN_UserTest as u2 on (u1.userName = u2.userName) and u1.id != u2.id set u1.userName = CONCAT(u1.userName, '-', right(MD5(rand()),5));

userId最小的不能更新...

select min(userId) from PN_UserTest group by hex(username) having count(*) > 1;

最后语句是:

update PN_UserTest as u1 inner join PN_UserTest as u2 on (hex(u1.userName) = hex(u2.userName)) and u1.id != u2.id set u1.userName = CONCAT(u1.userName, '-', right(MD5(rand()),5))
 where u1.id not in (select min(id) from (select * from PN_UserTest) a group by hex(a.username) having count(*) > 1);

注意!!! where in 里 要先用虚表a 先保存 PN_UserTest的最小id, 因为mysql不能先select出同一表中的某些值,再update这个表(在同一语句中) userName 也要带hex才能真正区分emoji之类的字符集, 自行搜索下mysql collocate 看下原理.
注意2 在我们只有几十万用户的数据库,用这个语句就崩了,原因是hex不能用到索引.
解决办法是SELECT group_concat(userId),username as cnt
FROM PN_User
GROUP BY hex(username)
HAVING cnt > 1
查出,然后手动插到where条件里..

更新

语句其实还是能优化的!!!!!

update PN_User u1 join (
(SELECT MIN(userId) as userId,userName
 FROM PN_User
 GROUP BY hex(userName)
 HAVING COUNT(*) > 1)
) uid
on uid.userId != u1.userId and hex(u1.userName) = hex(uid.userName) and u1.userName = uid.userName
SET u1.userName = CONCAT(u1.userName, '-', RIGHT(MD5(rand()), 5));

这里

and hex(u1.userName) = hex(uid.userName) and u1.userName = uid.userName

是为了能启用userName索引,被函数包含的字段无法启用索引.

你可能感兴趣的:(mysql重命名已重名用户昵称)