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
我有一个 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
的行)。然后,它会删除所有其他内容。
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