我有一个表在一个PostgreSQL 8.3.8数据库,其上有没有钥匙/制约因素,并具有完全相同的价值多行。删除重复记录在PostgreSQL的
我想删除所有重复,只保留1每行的副本。
有特别是一个柱(命名为“键”),其可以被用于识别重复的(即,应该只存在为每个不同的“密钥”的一个条目)。
我该怎么做? (最好有一个SQL命令) 速度是不是在这种情况下,一个问题(只有几行)。
我有一个表在一个PostgreSQL 8.3.8数据库,其上有没有钥匙/制约因素,并具有完全相同的价值多行。删除重复记录在PostgreSQL的
我想删除所有重复,只保留1每行的副本。
有特别是一个柱(命名为“键”),其可以被用于识别重复的(即,应该只存在为每个不同的“密钥”的一个条目)。
我该怎么做? (最好有一个SQL命令) 速度是不是在这种情况下,一个问题(只有几行)。
DELETE FROM dupes a
WHERE a.ctid <> (SELECT min(b.ctid)
FROM dupes b
WHERE a.key = b.key);
我会用一个临时表:
create table tab_temp as
select distinct f1, f2, f3, fn
from tab;
然后,删除tab
和重命名tab_temp
到tab
。
这种做法并不占触发器,索引和统计。当然,你可以添加它们,但它也增加了很多工作。 – Jordan
不是每个人都需要这个。这种方法非常快速,比没有索引的200k电子邮件(varchar 250)更好。 –
我要创建我自己的版本。由@a_horse_with_no_name编写的版本在我的表(21M行)上太慢了。而@rapimo根本不会删除dups。
以下是我对PostgreSQL的9.5
DELETE FROM your_table
WHERE ctid IN (
SELECT unnest(array_remove(all_ctids, actid))
FROM (
SELECT
min(b.ctid) AS actid,
array_agg(ctid) AS all_ctids
FROM your_table b
GROUP BY key1, key2, key3, key4
HAVING count(*) > 1) c);
使用我尝试这样做:
DELETE FROM tablename
WHERE id IN (SELECT id
FROM (SELECT id,
ROW_NUMBER() OVER (partition BY column1, column2, column3 ORDER BY id) AS rnum
FROM tablename) t
WHERE t.rnum > 1);
由Postgres的维基提供
:
这对我行之有效。我有一张表,包含重复值的术语。执行查询以填充所有重复行的临时表。然后我用临时表中的这些id运行了一条delete语句。值是包含重复项的列。
CREATE TEMP TABLE dupids AS
select id from (
select value, id, row_number()
over (partition by value order by value)
as rownum from terms
) tmp
where rownum >= 2;
delete from [table] where id in (select id from dupids)
既适用于普通的SQL和PostgreSQL(也能在AWS红移)
DROP TABLE IF EXISTS backupOfTheTableContainingDuplicates;
CREATE TABLE aNewEmptyTemporaryOrBackupTable
AS SELECT DISTINCT * FROM originalTableContainingDuplicates;
TRUNCATE TABLE originalTableContainingDuplicates;
INSERT INTO originalTableContainingDuplicates SELECT * FROM
aNewEmptyTemporaryOrBackupTable ;
DROP TABLE aNewEmptyTemporaryOrBackupTable ;
说明上述SQL脚本
所以,
第1查询可以确保,如果您有任何原始表包含备份/临时表g重复,然后首先删除该表。
的第二查询,创建一个新的表(临时/备份)表与包含重复原始表的唯一条目,所以新的临时表是相同的与原始表减去重复条目。
第三查询,截断或清空原来的表。
第四个查询,将临时表中的所有唯一条目插入或复制到最近被截断的原始表(因此没有数据)。执行此查询后,原始表将填充临时表中的UNIQUE数据。
第五个查询,删除/删除不必要的临时表。
所以最终结果是,原始表只有唯一的条目,没有重复。
这是快速和简洁:
DELETE FROM dupes T1
USING dupes T2
WHERE T1.ctid < T2.ctid -- delete the older versions
AND T1.key = T2.key; -- add more columns if needed
这是优秀的! – user151496
完美,谢谢!我不知道ctid –
不要使用它,它太慢了! –
尽管这个解决方案肯定有效,但@rapimo的[下面的解决方案](https://stackoverflow.com/a/12963112/1156554)执行得更快。我认为这与内部select语句执行N次(对于dupes表中的所有N行)而不是另一个解决方案中正在执行的分组有关。 – David