我在PostgreSQL 8.3.8数据库中有一个表,该表上没有键/约束,并且有多个行,它们的值完全相同。
我想删除所有重复项,并且每行仅保留1个副本。
特别是有一列(称为“密钥”)可用于标识重复项(即,每个不同的“密钥”应该只存在一个条目)。
我怎样才能做到这一点?(最好是使用单个SQL命令)在这种情况下,速度不是问题(只有几行)。
我在PostgreSQL 8.3.8数据库中有一个表,该表上没有键/约束,并且有多个行,它们的值完全相同。
我想删除所有重复项,并且每行仅保留1个副本。
特别是有一列(称为“密钥”)可用于标识重复项(即,每个不同的“密钥”应该只存在一个条目)。
我怎样才能做到这一点?(最好是使用单个SQL命令)在这种情况下,速度不是问题(只有几行)。
Answers:
DELETE FROM dupes a
WHERE a.ctid <> (SELECT min(b.ctid)
FROM dupes b
WHERE a.key = b.key);
更快的解决方案是
DELETE FROM dups a USING (
SELECT MIN(ctid) as ctid, key
FROM dups
GROUP BY key HAVING COUNT(*) > 1
) b
WHERE a.key = b.key
AND a.ctid <> b.ctid
ctid
?
这是快速而简洁的:
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
另请参阅我的答案,如何删除包含唯一标识符的重复行,其中包括更多信息。
ctid
指向表中记录的物理位置。与我当时在注释中写的相反,使用小于运算符不一定指向较旧的版本,因为ct可以环绕,而ctid较低的值实际上可能是较新的。
min(ctid)
吗?而您正在保留更新的?谢谢!
我尝试了这个:
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 Wiki提供:
id
包括在内),则此列将不起作用。
id
... 3重复的第一个
我将使用一个临时表:
create table tab_temp as
select distinct f1, f2, f3, fn
from tab;
然后,删除tab
并重命名tab_temp
为tab
。
DROP TABLE IF EXISTS tmp; CREATE TABLE tmp as ( SELECT * from (SELECT DISTINCT * FROM your_table) as t ); DELETE from your_table; INSERT INTO your_table SELECT * from tmp; DROP TABLE tmp;
我必须创建自己的版本。@a_horse_with_no_name编写的版本在我的表(2100万行)上太慢了。@rapimo根本不会删除公仔。
这是我在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);
另一种方法(仅当您id
在表中有任何唯一字段时才起作用),按列查找所有唯一ID,并删除不在唯一列表中的其他ID
DELETE
FROM users
WHERE users.id NOT IN (SELECT DISTINCT ON (username, email) id FROM users);
怎么样:
与 u AS(SELECT DISTINCT * FROM your_table), x AS(从your_table中删除) 插入your_table SELECT * FROM u;
我一直在担心执行顺序,是否会在SELECT DISTINCT之前发生DELETE,但对我来说很好。并且具有不需要任何有关表结构的知识的额外好处。
json
),则将无法使用。
这对我来说很好。我有一个表,术语,其中包含重复的值。运行查询以使用所有重复的行填充临时表。然后,我在临时表中运行带有这些id的delete语句。value是包含重复项的列。
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)