为什么我需要运行此脚本两次以删除所有重复项?

eno*_*non 0 mysql sql

我做的是创建一个名为Rent2的临时表来存放我的客户已注册的所有重复模块,然后在删除临时表之前执行删除内部连接语句.

但完成后总会留下重复的副本.我在这做错了什么?

CREATE  TABLE IF NOT EXISTS `tblRent2` (
  `IdRent` INT(11) NOT NULL)
ENGINE = InnoDB;

INSERT INTO tblRent2 (SELECT IdRent FROM tblRent WHERE IdModule = 1 GROUP BY IdClient HAVING COUNT(IdModule) > 1);
INSERT INTO tblRent2 (SELECT IdRent FROM tblRent WHERE IdModule = 2 GROUP BY IdClient HAVING COUNT(IdModule) > 1);
INSERT INTO tblRent2 (SELECT IdRent FROM tblRent WHERE IdModule = 3 GROUP BY IdClient HAVING COUNT(IdModule) > 1);
INSERT INTO tblRent2 (SELECT IdRent FROM tblRent WHERE IdModule = 4 GROUP BY IdClient HAVING COUNT(IdModule) > 1);
INSERT INTO tblRent2 (SELECT IdRent FROM tblRent WHERE IdModule = 5 GROUP BY IdClient HAVING COUNT(IdModule) > 1);
INSERT INTO tblRent2 (SELECT IdRent FROM tblRent WHERE IdModule = 6 GROUP BY IdClient HAVING COUNT(IdModule) > 1);
INSERT INTO tblRent2 (SELECT IdRent FROM tblRent WHERE IdModule = 999 GROUP BY IdClient HAVING COUNT(IdModule) > 1);

DELETE r.* FROM tblRent r INNER JOIN tblRent2 r2 ON 
r.idRent = r2.idRent;

SELECT * FROM tblRent2;

DROP TABLE tblRent2;
Run Code Online (Sandbox Code Playgroud)

原始表如下所示:

IdRent | IDClient  | IdModule
1      |  30       |   999
2      |  30       |   999
3      |  31       |   1
4      |  31       |   1
Run Code Online (Sandbox Code Playgroud)

这些都是主键.

Boh*_*ian 5

一个更好的问题是你为什么使用临时表?

只需加入表格:

DELETE r2
FROM tblRent r
JOIN tblRent r2
    ON r.IDClient = r2.IDClient
    AND r.IdModule = r2.IdModule
    AND r.idRent < r2.idRent
Run Code Online (Sandbox Code Playgroud)

这也将清理三次,总是留下最低的行idRent.

一个关键点(原谅双关语)是额外的连接条件r.idRent < r2.idRent,它阻止行连接到它们自己(通过具有不等的id),并选择最后添加的行进行删除(通过强制一个id小于另一个).使用r.idRent != r2.idRent会导致删除两个重复项.