今天遇到一个问题。如何删除一种数据表中某个字段的重复数据记录?
例如有表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) ;