MySQL 删除带主键的重复行

MySQL removing Duplicate Rows with Primary Key

我有一个 table,其中包含以下列:

ID(primary key),
USER,
ACTION
TIME
LOCATION

我正在尝试 删除重复条目 同时使用以下列:USER, ACTION, TIME, LOCATION

我写了以下查询:

DELETE FROM test.testlogins  
WHERE id IN (SELECT * 
             FROM (SELECT id FROM test.testlogins 
                   GROUP BY USER, ACTION, TIME, LOCATION HAVING (COUNT(*) > 1)
                  ) AS A
            );

但是,当我执行它时,我每 运行 只删除了 1 行。我的测试数据有大约 40 多行是重复的,每行都分配了一个单独的 id.

DELETE t1.*
FROM
  testlogins t1 INNER JOIN testlogins t2
  ON t1.user=t2.user
     AND t1.action=t2.action
     AND t1.time=t2.time
     AND t2.location=t2.location
     AND t1.id>t2.id

如果要保留 ID 最小的行,可以使用 t1.id>t2.id,如果要保留 ID 最大的行,可以使用 t1.id<t2.id

编写此查询的另一种方法是:

DELETE tl
    FROM test.testlogins tl LEFT JOIN
         (SELECT MIN(id) as id
          FROM test.testlogins 
          GROUP BY USER, ACTION, TIME, LOCATION
         ) tokeep
         ON tl.id = tokeep.minid
    WHERE tokeep.id IS NULL;

据推测,您一次只删除一个 ID 的原因是因为您语句中的 group by returns 只有一个 ID - 而这就是您要删除的 ID。如果列的一种组合出现 40 次,则每个 delete.

仅删除该组中的一个 ID

另一方面,此方法找到要保留的行(任意具有最小 id 的行)。然后,它会删除所有其他内容。

DELETE FROM testlogins  
WHERE EXISTS ( SELECT 'a'
               FROM testlogins t2
               WHERE t2.USER = testlogins.USER
               AND t2.ACTION= testlogins.ACTION
               AND t2.TIME = testlogins.TIME 
               AND t2.LOCATION = testlogins.LOCATION 
               AND t2.ID > testlogins.ID
              )

删除具有相同 属性 且 id 小于 max

的所有行

最简单的解决方案是使用 ALTER IGNORE 向 table 添加唯一索引。如果 table 大小不是很大,这将避免将来出现此问题。

ALTER IGNORE TABLE testlogins ADD UNIQUE KEY (USER, ACTION, TIME, LOCATION)

使用新的唯一索引在其他一些数据库中创建一个新的 table 并使用 INSERT IGNORE

将所有数据加载到新的 table