我有一个包含以下列的表:
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
。
答案 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较低的行