从同一表中选择和删除

时间:2017-01-03 11:54:32

标签: mysql sql

在编写数据库转换脚本时,我遇到了存在重复记录的问题,我的目的是找到这些并删除重复项。我绝不是SQL的专家所以请寻求建议!

到目前为止,我能够找到和删除重复记录(如果group_name和level)相同的最好的事情就是这个

DELETE FROM achievements
WHERE group_name IN (SELECT concat(group_name, level)
                     FROM achievements
                     GROUP BY group_name, level
                     HAVING count(*) >1);

但它给了我以下错误

  

[Err] 1093 - 表'成就'被指定两次,既作为'DELETE'的目标又作为单独的数据来源

这是我目前的数据; https://gist.github.com/Diddyy/13842901c830c19c21488613c9d27c92

根据该数据,有3个重复项(group_name后跟级别);
ACH_CameraPhotoCount 5
ACH_FootballGoalScoredInRoom 1
ACH_FootballGoalScoredInRoom 2

我把它们分类为重复项,因为已经有一个具有相同名称和级别的条目。

我的最终结果是删除了3个副本,但留下了其中一个,因此它仍然存在。

注意,允许重复的group_name。允许重复级别。但我不想要的是具有相同级别的group_name不止一次。

我似乎无法为此提出解决方案,而且我不太确定concat会是最好的方法吗?

对任何解决方案开放,谢谢!

1 个答案:

答案 0 :(得分:1)

在MySQL中删除重复项的常用方法是使用join。以下内容删除了多次出现的所有 group_name

delete a
    from achievements a join
         (select group_name, min(level) as minlevel
          from achievements a
          group by group_name
          having count(*) > 1
         ) aa
         on a.group_name = aa.group_name;

以下是更常见的事情。它保持一个“重复”行,比如说具有最低级别的行:

delete a
    from achievements a join
         (select group_name, min(level) as minlevel
          from achievements a
          group by group_name
          having count(*) > 1
         ) aa
         on a.group_name = aa.group_name
    where a.level > aa.level;

编辑:

您可以使用group_namelevel

执行相同的操作
delete a
    from achievements a join
         (select group_name, level, min(id) as minid
          from achievements a
          group by group_name, level
          having count(*) > 1
         ) aa
         on a.group_name = aa.group_name and a.level = aa.level
    where a.id > aa.minid;