在两列重复

时间:2017-11-29 11:21:19

标签: mysql duplicates

我有一个大的MySql表,我需要从中删除重复项 - 要符合重复条件,一行与两列上的另一行匹配:

SELECT * FROM JwDistanceSurnames n1, JwDistanceSurnames n2 
WHERE n1.JwDistanceSurnameId > n2.JwDistanceSurnameId
AND n1.Surname1 = n2.Surname1
AND n1.Surname2 = n2.Surname2
LIMIT 1000;      

因为它是一张大桌子,所以我想分批进行。我的理解是我应该能够使用LIMIT来实现这一目标。但是,这不会执行,引用语法错误:

DELETE n1 FROM JwDistanceSurnames n1, JwDistanceSurnames n2 
WHERE n1.JwDistanceSurnameId > n2.JwDistanceSurnameId
AND n1.Surname1 = n2.Surname1
AND n1.Surname2 = n2.Surname2
LIMIT 1000;

错误是什么?是不是可以使用这种简单的方法进行批处理?

MCVE:

CREATE TABLE `JwDistanceSurnames` (
  `JwDistanceSurnameId` int(11) NOT NULL AUTO_INCREMENT,
  `Surname1` varchar(999) DEFAULT NULL,
  `Surname2` varchar(999) DEFAULT NULL,
  `JwScore` double NOT NULL,
  PRIMARY KEY (`JwDistanceSurnameId`),
  KEY `Surname1` (`Surname1`),
  KEY `Surname2` (`Surname2`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

INSERT INTO `JwDistanceSurnames`
(`JwDistanceSurnameId`, `Surname1`, `Surname2`, `JwScore`)
VALUES (null,'williamsom' ,'williamson' ,0.959999999999998);

重复插入几次。然后运行删除。预期输出是单行,具有给定值。保留哪一行并不重要。

错误是:

  

错误代码:1064。您的SQL语法有错误;检查   手册,对应右边的MySQL服务器版本   使用的语法靠近  ORDER BY n1.JwDistanceSurnameId LIMIT 1000'在   第5行

1 个答案:

答案 0 :(得分:2)

this SO question开始,当引用多个表时,LIMIT语句似乎无法使用DELETE。解决此问题的一个技巧是在子查询中使用LIMIT来标识要删除的记录,然后再联接回目标表:

DELETE t1
FROM JwDistanceSurnames t1
INNER JOIN
(
    SELECT n1.JwDistanceSurnameId
    FROM JwDistanceSurnames n1
    INNER JOIN JwDistanceSurnames n2 
        ON n1.JwDistanceSurnameId > n2.JwDistanceSurnameId
    WHERE n1.Surname1 = n2.Surname1 AND n1.Surname2 = n2.Surname2
    ORDER BY <some_column>    -- IMPORTANT! without this you may get random records
    LIMIT 1000
) t2
    ON t1.JwDistanceSurnameId = t2.JwDistanceSurnameId;

因此,标记为t2的子查询使用LIMIT一次识别1000个记录的批次以进行删除,然后我们使用另一个连接来实际标记这些目标记录。

另请注意,在没有LIMIT的情况下使用ORDER BY并不是一个定义明确的事情,因为SQL表是在无序的记录集上建模的。如果您有一些业务逻辑确定应删除批次的顺序,那么请考虑添加ORDER BY子句(除非它真的无关紧要,这对我来说似乎不太重要)。