在没有临时表的情况下,如何删除MySQL表中的所有重复记录

在没有临时表的情况下,如何删除MySQL表中的所有重复记录,mysql,sql,duplicates,sql-delete,unique-index,Mysql,Sql,Duplicates,Sql Delete,Unique Index,我已经在这方面看到了很多变化,但没有什么能完全符合我的目标 我有一个表,TableA,其中包含用户对可配置问卷的回答。这些列是成员id、测验编号、问题编号、答案编号 不知怎的,一些成员提交了两次答案。因此,我需要删除重复的记录,但要确保留下一行 没有主列,因此可能有两行或三行数据完全相同 是否有删除所有重复项的查询?这不使用临时表,而是使用实际表。如果问题只与临时表有关,而与表创建或删除表无关,则这将起作用: SELECT DISTINCT * INTO TableA_Verify FROM T

我已经在这方面看到了很多变化,但没有什么能完全符合我的目标

我有一个表,
TableA
,其中包含用户对可配置问卷的回答。这些列是
成员id、测验编号、问题编号、答案编号

不知怎的,一些成员提交了两次答案。因此,我需要删除重复的记录,但要确保留下一行

没有主列,因此可能有两行或三行数据完全相同


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

这不使用临时表,而是使用实际表。如果问题只与临时表有关,而与表创建或删除表无关,则这将起作用:

SELECT DISTINCT * INTO TableA_Verify FROM TableA;

DROP TABLE TableA;

RENAME TABLE TableA_Verify TO TableA;

在您的表中添加唯一索引

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

您可以删除所有寄存器(
delete from TableA;
),然后用来自TableA\u Verify的寄存器填充原始表,而不是
drop table TableA
)。这样,您就不会丢失对原始表的所有引用(索引,…)


感谢jveirasv提供上述答案

如果需要删除特定列集合的重复项,可以使用此选项(例如,如果表中有不同的时间戳)


在表上添加唯一索引:

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

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

# 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
  • 创建临时表并存储不同(非重复)的值
  • 把原来的桌子弄空
  • 从临时表向原始表插入值
  • 删除临时表

  • 在使用数据库之前,最好先备份数据库

    如评论中所述,如果项目重复多次,则必须多次运行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语句确保重复项彼此相邻显示)。然后删除重复记录。我删除末尾的
    replicate
    列,使其恢复到原始状态


    看起来,
    altertableignore
    也可能很快消失:

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

    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
    

    在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
    
    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
    
    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
    
    从“yourTableName”n1、“yourTableName”n2中删除n1,其中n1.id
    在删除重复项后,是否有理由不创建可以通过简单的drop table语句删除的临时表?我可以为您提供SQL来创建一个只有唯一记录的临时表,从原始表中删除记录,加载唯一数据,然后删除临时表。如果它不是一个庞大的数据库,这应该不会花太长时间。这里有一篇关于这个过程的好文章:我正在寻找一个很容易(从最广泛的意义上)即时重复的解决方案。使用额外的表(temp或not)意味着在检测到此情况时关闭站点。最好的解决办法是确保它从一开始就不会发生,但在那之前,我希望定期进行检查/修复,以确保报告不会给出不可靠的结果。正如我在回答中提到的,在您的表上创建一个索引,它将删除重复的数据,也不允许您在将来添加重复的数据。我将继续并选择此作为答案。最后,我将不得不使用临时表来清理房间,但我将确保添加唯一索引,以便将来不会出现此问题。现在我只需要弄清楚事情是如何被复制的。注意:如果您的表包含同一行的3个或更多重复项,您将需要多次运行此操作。如果有关于使用IGNORE添加唯一索引的后果的解释,这个答案将更有帮助:显然,它会删除重复的行?我们知道它是否保留了第一个吗?看起来,
    alter ignore table
    可能很快就会消失:@juacala是正确的:“从MySQL 5.7.4开始,alter table的ignore子句被删除,它的使用产生了一个错误。”谢谢,它工作了,但我得到了一个警告:1681'ignore'已被弃用,将在未来的版本中删除。重复:1警告:1