2017-01-03 2 views
1

При написании сценария преобразования базы данных я столкнулся с проблемой дублирования записей, моя цель - найти их и удалить дубликаты. Я никоим образом не являюсь экспертом по SQL, поэтому ищите рекомендации!Выбор и удаление из той же таблицы

Самое лучшее, что я смог придумать настолько далеко, чтобы найти и удалить дубликаты записей (если group_name и уровень) одни и те же это

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 дубликата (имя_группы, за которым следует уровень);
ACH_CameraPhotoCount 5
ACH_FootballGoalScoredInRoom 1
ACH_FootballGoalScoredInRoom 2

I класс это как дублирующий, как уже есть запись с таким же именем и уровня.

Мой конечный результат - удалить 3 дубликата, но оставить позади один из них, чтобы он все еще существовал.

Примечание. Допускается повторное имя группы. Допускается повторный уровень. Но то, чего я не хочу, является group_name с одинаковым уровнем более одного раза.

Я не могу придумать решение для этого, так как я не слишком уверен, что concat будет лучшим способом?

Открыть любое решение, спасибо!

+0

Вы можете предоставить образцы данных и желаемые результаты? –

+0

@ GordonLinoff Добавлена ​​информация, извинения! –

ответ

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; 

EDIT:

Вы можете сделать то же самое с group_name и level:

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; 
+0

Это не похоже на конечный результат, на который я надеюсь, это была моя ошибка, поскольку я не объяснил, чего я хочу достичь точно. Я хочу удалить дубликаты, где уровень_группы + уже существует. Примером в моих данных будет ACH_CameraPhotoCount - 5. Это дубликат, так как уже есть запись для group_name ACH_CameraPhotoCount с уровнем 5. См. «Первоначальное сообщение» для моих текущих данных. Сожалею! –

+0

Большое вам спасибо за ваше время и решение, он достиг именно того, на что я надеялся! –

Смежные вопросы