MySQL使用主键删除重复行

时间:2015-04-11 11:56:48

标签: mysql sql primary-key

我有一个包含以下列的表:

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

4 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:2)

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

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

使用新的唯一索引在其他数据库中创建一个新表,并使用INSERT IGNORE将所有数据加载到新表中

答案 2 :(得分:0)

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

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只返回一个id - 这就是你要删除的id。如果列的一个组合出现40次,则每个delete只删除此组中的一个ID。

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

答案 3 :(得分:0)

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较低的行