我有一个带有大量列的PostgreSQL表。该表没有主键,现在包含几行,它们是另一行的100%复制。
如何删除这些重复项而不删除原始副本?
我在related question上找到了这个答案,但是我必须拼写出每个列的名称,这很容易出错。 如何避免不必了解表结构?
示例:
给予
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!')
答案 0 :(得分:0)
根据this answer中的建议,使用system column ctid
来区分原本相同的行的物理副本。
为避免为行拼出不存在的“键”,只需使用row constructor 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中进行尝试。