MySQL使用主键删除重复行
我有一个包含以下列的表:MySQL使用主键删除重复行,mysql,sql,primary-key,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, A
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编写此查询的另一种方法是:
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最小的行)。然后,它删除所有其他内容
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
向表中添加唯一索引。如果表的大小不是很大的话,这将避免将来的问题
ALTER IGNORE TABLE testlogins ADD UNIQUE KEY (USER, ACTION, TIME, LOCATION)
或
使用新的唯一索引在其他数据库中创建一个新表,并使用INSERT IGNORE将所有数据加载到新表中这在MySQL中不起作用,因为子查询无法引用正在删除行的表。这可以按预期工作(删除多个重复项)但我还打算尝试使用它作为触发器,以防止在添加重复项时发生相同的情况。关于如何防止添加重复项的任何想法。@silverzpeed您应该使用create UNIQUE INDEX idx\u userlogins on testlogins(用户、操作、时间、位置)
在删除服务器上有一个脚本,它生成插入脚本并执行插入。如果存在重复项,我在日志中看到的错误输出是否会影响插入。@silverzpeed请查看我的其他答案。是的,如果存在唯一索引,则在插入重复项时将出现错误。。。您可以使用INSERT。。在重复…
语法中,忽略重复的插入而不引发错误