Подтвердить что ты не робот

Как удалить все повторяющиеся записи в таблице MySQL без временных таблиц

Я видел несколько вариантов этого, но ничто не сравнимо с тем, что я пытаюсь выполнить.

У меня есть таблица TableA, в которой содержатся ответы, заданные пользователями для настраиваемых вопросников. Столбцы: member_id, quiz_num, question_num, answer_num.

Как-то несколько членов получили свои ответы дважды. Поэтому мне нужно удалить дублированные записи, но убедитесь, что одна строка оставлена ​​позади. Нет "первичного" столбца, поэтому могут быть две или три строки с одинаковыми данными.

Есть ли запрос для удаления всех дубликатов?

4b9b3361

Ответ 1

Добавьте Уникальный индекс в таблицу:

ALTER IGNORE TABLE `TableA`   
ADD UNIQUE INDEX (`member_id`, `quiz_num`, `question_num`, `answer_num`);

Другой способ сделать это:

Добавьте первичный ключ в свою таблицу, тогда вы можете легко удалить дубликаты из своей таблицы, используя следующий запрос:

DELETE FROM member  
WHERE id IN (SELECT * 
             FROM (SELECT id FROM member 
                   GROUP BY member_id, quiz_num, question_num, answer_num HAVING (COUNT(*) > 1)
                  ) AS A
            );

Ответ 2

Вместо drop table TableA вы можете удалить все регистры (delete from TableA;), а затем заполнить исходную таблицу регистрами, исходящими из TableA_Verify (insert into TAbleA select * from TAbleA_Verify). Таким образом, вы не потеряете все ссылки на исходную таблицу (индексы,...)

CREATE TABLE TableA_Verify AS SELECT DISTINCT * FROM TableA;

delete from TableA;

INSERT INTO TableA SELECT * FROM TAbleA_Verify;

DROP TABLE TableA_Verify;

Ответ 3

Это не использует таблицы TEMP, а вместо этого - реальные таблицы. Если проблема связана только с временными таблицами, а не с таблицей создания или отбрасыванием таблиц, это будет работать:

SELECT DISTINCT * INTO TableA_Verify FROM TableA;

DROP TABLE TableA;

RENAME TABLE TableA_Verify TO TableA;

Ответ 4

Благодаря jveirasv для ответа выше.

Если вам нужно удалить дубликаты определенных наборов столбцов, вы можете использовать это (если у вас есть временная метка в таблице, которая может меняться, например)

CREATE TABLE TableA_Verify AS SELECT * FROM TableA WHERE 1 GROUP BY [COLUMN TO remove duplicates BY];

DELETE FROM TableA;

INSERT INTO TableA SELECT * FROM TAbleA_Verify;

DROP TABLE TableA_Verify;

Ответ 5

Добавьте уникальный индекс в таблицу:

ALTER IGNORE TABLE TableA   
ADD UNIQUE INDEX (member_id, quiz_num, question_num, answer_num);

работает очень хорошо

Ответ 6

Если вы не используете какой-либо первичный ключ, выполните следующие запросы за один раз. Заменяя значения:

# table_name - Your Table Name
# column_name_of_duplicates - Name of column where duplicate entries are found

create table table_name_temp like table_name;
insert into table_name_temp select distinct(column_name_of_duplicates),value,type from table_name group by column_name_of_duplicates;
delete from table_name;
insert into table_name select * from table_name_temp;
drop table table_name_temp
  • создать временную таблицу и сохранить отдельные (не дублируемые) значения
  • сделать пустую исходную таблицу
  • Вставить значения в исходную таблицу из таблицы temp
  • удалить временную таблицу

Всегда рекомендуется делать резервную копию базы данных, прежде чем играть с ней.

Ответ 7

Как отмечено в комментариях, запрос в ответе Saharsh Shah должен выполняться несколько раз, если элементы дублируются более одного раза.

Здесь решение, которое не удаляет какие-либо данные, и сохраняет данные в исходной таблице все время, позволяя удалять дубликаты, сохраняя таблицу "live":

alter table tableA add column duplicate tinyint(1) not null default '0';

update tableA set
duplicate=if(@member_id=member_id
             and @quiz_num=quiz_num
             and @question_num=question_num
             and @answer_num=answer_num,1,0),
member_id=(@member_id:=member_id),
quiz_num=(@quiz_num:=quiz_num),
question_num=(@question_num:=question_num),
answer_num=(@answer_num:=answer_num)
order by member_id, quiz_num, question_num, answer_num;

delete from tableA where duplicate=1;

alter table tableA drop column duplicate;

В основном это проверяет, совпадает ли текущая строка с последней строкой, и если это так, отмечает ее как дубликат (инструкция заказа гарантирует, что дубликаты будут отображаться рядом друг с другом). Затем вы удаляете дубликаты записей. Я удаляю столбец duplicate в конце, чтобы вернуть его в исходное состояние.

Похоже, что alter table ignore также скоро исчезнет: http://dev.mysql.com/worklog/task/?id=7395

Ответ 8

Альтернативным способом было бы создать новую временную таблицу с той же структурой.

CREATE TABLE temp_table AS SELECT * FROM original_table LIMIT 0

Затем создайте первичный ключ в таблице.

ALTER TABLE temp_table ADD PRIMARY KEY (primary-key-field)

Наконец, скопируйте все записи из исходной таблицы, игнорируя повторяющиеся записи.

INSERT IGNORE INTO temp_table AS SELECT * FROM original_table

Теперь вы можете удалить исходную таблицу и переименовать новую таблицу.

DROP TABLE original_table
RENAME TABLE temp_table TO original_table