如何删除没有临时表的MySQL表中的所有重复记录

时间:2012-12-26 21:15:45

标签: mysql sql duplicates sql-delete unique-index

我已经看到了很多这方面的变化,但没有什么能与我想要完成的事情完全匹配。

我有一张表TableA,其中包含用户对可配置问卷的答案。列为member_id, quiz_num, question_num, answer_num

不知何故,有几位成员提交了两次答案。所以我需要删除重复的记录,但要确保留下一行。

没有主要列,因此可能有两行或三行都具有完全相同的数据。

是否有查询删除所有重复项?

9 个答案:

答案 0 :(得分:101)

在桌面上添加唯一索引

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
            );

答案 1 :(得分:13)

这不使用TEMP表,而是使用真实表。如果问题只是临时表而不是关于表创建或删除表,那么这将起作用:

SELECT DISTINCT * INTO TableA_Verify FROM TableA;

DROP TABLE TableA;

RENAME TABLE TableA_Verify TO TableA;

答案 2 :(得分:13)

您可以删除所有寄存器(drop table TableA),然后使用来自TableA_Verify(delete from TableA;)的寄存器填充原始表,而不是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 :(得分:7)

感谢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;

答案 4 :(得分:7)

在桌面上添加唯一索引:

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

工作得很好

答案 5 :(得分:3)

如果您没有使用任何主键,则只需一次执行以下查询即可。通过替换值:

# 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
  1. 创建临时表并存储不同(非重复)值
  2. 制作空原始表
  3. 从临时表
  4. 向原始表插入值
  5. 删除临时表
  6. 建议您在使用数据库之前备份数据库。

答案 6 :(得分:1)

如评论中所述,如果项目重复多次,则Saharsh Shah的答案中的查询必须多次运行。

这是一个不会删除任何数据的解决方案,并且会将数据保留在原始表格中,从而可以删除重复项目,同时保持表格的生存状态':

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;

这基本上检查当前行是否与最后一行相同,如果是,则将其标记为重复(order语句确保重复项将显示在彼此旁边)。然后删除重复的记录。我删除了末尾的duplicate列,使其恢复到原始状态。

看起来alter table ignore也可能很快消失:http://dev.mysql.com/worklog/task/?id=7395

答案 7 :(得分:1)

另一种方法是创建一个具有相同结构的新临时表。

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

答案 8 :(得分:0)

在mysql 5中测试。不了解其他版本。 如果您要保留ID值最低的行:

DELETE n1 FROM 'yourTableName' n1, 'yourTableName' n2 WHERE n1.id > n2.id AND n1.member_id = n2.member_id and n1.answer_num =n2.answer_num

如果要保留具有最高id值的行:

DELETE n1 FROM 'yourTableName' n1, 'yourTableName' n2 WHERE n1.id < n2.id AND n1.member_id = n2.member_id and n1.answer_num =n2.answer_num