如何在没有主键的情况下删除PostgreSQL表中100%重复的行



我有一个PostgreSQL表,它有很多列。该表没有主键,现在包含的几行与另一行100%重复。

如何在不删除原件的情况下删除这些重复项

我在一个相关的问题上找到了这个答案,但我必须拼写出每一个列名,这很容易出错我怎样才能避免对表格结构一无所知

示例:

给定

create table duplicated (
id int,
name text,
description text
);
insert into duplicated
values (1, 'A', null), 
(2, 'B', null),
(2, 'B', null),
(3, 'C', null), 
(3, 'C', null), 
(3, 'C', 'not a DUPE!');

删除后,应保留以下行:

(1, 'A', null) 
(2, 'B', null)
(3, 'C', null) 
(3, 'C', 'not a DUPE!')

如本答案中所建议的,使用系统列ctid来区分其他相同行的物理副本。

为了避免为行拼写出不存在的"key",只需使用行构造函数row(table),它返回包含select * from table:返回的整行的行值

DELETE FROM duplicated
USING (
SELECT MIN(ctid) as ctid, row(duplicated) as row
FROM duplicated 
GROUP BY row(duplicated) HAVING COUNT(*) > 1
) uniqued
WHERE row(duplicated) = uniqued.row
AND duplicated.ctid <> uniqued.ctid;

你可以在这个DbFiddle中尝试一下。

最新更新