尝试编写一个返回要删除的行的查询。假设 的组合(group_id,person_id,sequence)
是唯一的,并且您没有 NULL 值...
SELECT t.*
FROM my_table t
JOIN ( SELECT o.group_id
, o.person_id
, MAX(o.sequence) AS max_sequence
FROM my_table o
GROUP BY o.group_id, o.person_id
HAVING COUNT(*) > 1
) d
ON d.group_id = t.group_id
AND d.person_id = t.person_id
AND d.max_sequence = t.sequence
我们可以通过将关键字替换为关键字来将其转换为DELETE
语句。SELECT
DELETE
或者,当我使用与此类似的语句删除行时,我通常会创建一个表作为我要删除的行的“备份”。
只需在 SELECT 前面加上CREATE TABLE some_new_table_name AS
.
然后,我们可以在 DELETE 查询中引用“已保存”的行
DELETE t.*
FROM my_table t
JOIN some_new_table_name d
ON d.group_id = t.group_id
AND d.person_id = t.person_id
AND d.max_sequence = t.sequence
这种方法只得到“一个”重复项。如果原始查询的计数值大于 2,那么我们需要重复此操作足够多次,每次删除最高的序列值,重复此操作直到没有大于 1 的计数值。
如果要删除很多重复项,我们可以使用稍微不同的模式一举将它们删除。
代替返回MAX(sequence)
(我们想要删除的行),我们可以改为返回MIN(sequence)
,我们想要保留的行。我们会改变谓词,
AND d.max_sequence = t.sequence
成为
AND d.min_sequence <> t.sequence
这样我们就删除了该行的所有行,group_id, person_id
但具有最小值的行除外。
我强烈建议您先写这个SELECT
,然后再将其转换为DELETE
语句。而且我还建议您对要删除的行进行良好的备份和/或“保存”副本。以防万一您需要恢复一些行。