zoukankan      html  css  js  c++  java
  • 关于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) ;

  • 相关阅读:
    Java接口总结
    java面向对象特点总结
    二分查找的两种实现方法
    关于Java的对象equals方法
    java加密枝术是怎样的?
    Java中子类和父类间的调用关系
    Java中字符串的完美度
    Java源代码不编译到字节码文件
    java生成6位随机数
    Struts2中ModelDriven的使用
  • 原文地址:https://www.cnblogs.com/gaorongyi/p/5003516.html
Copyright © 2011-2022 走看看