13

我阅读了所有相关的重复问题/答案,我发现这是最相关的答案:

INSERT IGNORE INTO temp(MAILING_ID,REPORT_ID) 
SELECT DISTINCT MAILING_ID,REPORT_IDFROM table_1
;

问题是我想删除 col1 和 col2 的重复项,但还想将 table_1 的所有其他字段包含到插入中。

我尝试以这种方式添加所有相关列:

INSERT IGNORE INTO temp(M_ID,MAILING_ID,REPORT_ID,
MAILING_NAME,VISIBILITY,EXPORTED) SELECT DISTINCT  
M_ID,MAILING_ID,REPORT_ID,MAILING_NAME,VISIBILITY,
EXPORTED FROM table_1
;


M_ID(int,primary),MAILING_ID(int),REPORT_ID(int),
MAILING_NAME(varchar),VISIBILITY(varchar),EXPORTED(int)

但它将所有行插入临时(包括重复项)

4

7 回答 7

33

删除多列重复行的最佳方法是最简单的方法:

添加唯一索引:

ALTER IGNORE TABLE your_table ADD UNIQUE (field1,field2,field3);

上面的 IGNORE 确保只保留第一个找到的行,其余的被丢弃。

(如果您需要未来的重复和/或知道它们不会再次发生,则可以删除该索引)。

于 2015-03-13T20:20:35.030 回答
21

这适用于任何版本的 MySQL,包括 5.7+。它还You can't specify target table 'my_table' for update in FROM clause通过使用双嵌套子查询来处理错误。它只删除一个重复行(后一个),因此如果您有 3 个或更多重复行,则可以多次运行查询。它从不删除唯一的行。

DELETE FROM my_table
WHERE id IN (
  SELECT calc_id FROM (
    SELECT MAX(id) AS calc_id
    FROM my_table
    GROUP BY identField1, identField2
    HAVING COUNT(id) > 1
  ) temp
)

我需要这个查询,因为我想在两列上添加一个 UNIQUE 索引,但是我需要先丢弃一些重复的行。

于 2019-01-30T18:40:57.037 回答
8

对于 Mysql:

DELETE t1 FROM yourtable t1 
  INNER JOIN yourtable t2 WHERE t1.id < t2.id 
    AND t1.identField1 = t2.identField1 
    AND t1.identField2 = t2.identField2;
于 2018-07-27T06:50:31.660 回答
4

您首先需要通过使用having子句对两个字段进行分组来查找重复项。

    Select identField1, identField2, count(*) FROM yourTable
        GROUP BY identField1, identField2
          HAVING count(*) >1

如果这返回了您想要的内容,您可以将其用作子查询并

  DELETE FROM yourTable WHERE field in (Select identField1, identField2, count(*) FROM yourTable
        GROUP BY identField1, identField2
          HAVING count(*) >1 )
于 2013-01-15T15:51:23.750 回答
2

注意:此解决方案是一种替代的老派解决方案。


如果你不能达到你想要的,那么你可以试试我的“oldschool”方法:

首先,运行此查询以获取重复记录:

select   column1,
         column2,
         count(*)
from     table
group by column1,
         column2
having   count(*) > 1
order by count(*) desc

之后,选择这些结果并将它们粘贴到记事本++中:

选择查询 粘贴到记事本上

现在通过使用notepad++的查找和替换特性替换它们;首先“删除”然后“插入”这样的查询(从现在开始,出于安全原因,我的值将是 AAAA)。

特别注意:请在 notepad++ 中的最后一行数据的末尾再创建一个新行,因为正则表达式匹配每行末尾的 '\r\n':

在此处输入图像描述

查找什么正则表达式:\D*(\d+)\D*(\d+)\D*\r\n

替换为字符串:delete from table where column1 = $1 and column2 = $2; insert into table set column1 = $1, column2 = $2;\r\n

现在最后,将这些查询粘贴到 MySQL Workbench 的查询控制台并执行。您只会看到每条重复记录出现一次。

在此处输入图像描述

此答案适用于仅由两列没有 ID 的关系表。我认为您可以将其应用于您的情况。

于 2016-06-23T10:23:22.480 回答
1

您始终可以通过将两个唯一字段分组来获取主 ID

select count(*), id as count from table group by col a, col b having count(*)>1;

接着

delete from table where id in ( select count(*), id as count from table group by col a, col b having count(*)>1) limit maxlimit;

你也可以使用max()代替limit

于 2017-05-30T09:26:48.177 回答
0

如果您在 select 子句 ex: 中选择多个列,则在大型数据集中 select x,y,z from table1。并且要求是基于两列删除重复项:从上面的示例中让 y,z 然后您可以使用下面的而不是使用“分组依据”和“子查询”的组合,这在性能上很差:

select x,y,z 
from (
select x,y,z , row_number() over (partition by y,z) as index_num
from table1) main
where main.index_num=1
于 2020-01-09T22:15:19.850 回答