关于MYSQL通过子查询删除重复数据的for update报错问题解决

今天遇到一个问题。如何删除一种数据表中某个字段的重复数据记录?

例如有表info,该表的title字段有很多重复数据,现在我们需要删除掉重复数据,只保留最早的一条。

利用Oracle是比较简单的,直接用ROWID即可解决:

DELETE FROM info WHERE ROWID NOT EXIST(SELECT MIN(ROWID) rid FROM info GROUP BY title) ;

但是用mysql删除的时候,却遇到了问题:

DELETE FROM info WHERE id NOT EXIST(SELECT MIN(id) id FROM info GROUP BY title) ;

此时,数据库报错:You can't specify target table 'info' for update in FROM clause;

通过for update我们不难猜出应该是由于mysql的悲观锁机制造成的,mysql不允许在进行select的同时对同一张表执行update操作。

此时有两种方式进行解决,一种是通过中间表:

根据子查询创建中间表:
CREATE TABLE temp AS (SELECT MIN(id) id FROM info GROUP BY title) ;
根据中间表中的结果数据删除目标数据表中的数据:
DELETE FROM info WHERE id NOT EXIST(SELECT id FROM temp) ;
删除中间表:
DROP TABLE temp ;

第二种方式是通过对子查询数据表创建别名的方式进行:

DELETE FROM info WHERE id NOT EXIST(SELECT id FROM (SELECT MIN(id) id FROM info GROUP BY title) temp) ;

 

posted @ 2015-11-28 21:44  Loeis.G  阅读(436)  评论(0编辑  收藏  举报