一、测试数据创建
postgres=# create table test_chongfu(id int not null default null,name char(50) default null,class int default null); CREATE TABLE postgres=# insert into test_chongfu values(1,'AA',1); INSERT 0 1 postgres=# insert into test_chongfu values(2,'AB',8); INSERT 0 1 postgres=# insert into test_chongfu values(3,'AB',8); INSERT 0 1 postgres=# insert into test_chongfu values(4,'BB',5); INSERT 0 1 postgres=# insert into test_chongfu values(5,'BD',7); INSERT 0 1 postgres=# insert into test_chongfu values(6,'BD',7); INSERT 0 1 postgres=# select * from test_chongfu; id | name | class ----+----------------------------------------------------+------- 1 | AA | 1 2 | AB | 8 3 | AB | 8 4 | BB | 5 5 | BD | 7 6 | BD | 7 (6 rows) postgres=# alter table test_chongfu add constraint pk1 primary key ("id"); ALTER TABLE postgres=# \d test_chongfu Table "public.test_chongfu" Column | Type | Collation | Nullable | Default --------+---------------+-----------+----------+-------------- id | integer | | not null | name | character(50) | | | NULL::bpchar class | integer | | | Indexes: "pk1" PRIMARY KEY, btree (id)
复制
二、存在唯一标识情况
如果删除重复数据的表里有除ctid外的唯一标识,可以利用这一列,我这里为id列。
postgres=# select * from test_chongfu; id | name | class ----+----------------------------------------------------+------- 1 | AA | 1 2 | AB | 8 3 | AB | 8 4 | BB | 5 5 | BD | 7 6 | BD | 7 (6 rows) postgres=# select * from test_chongfu where id not in (select min(id) from test_chongfu group by name,class); id | name | class ----+----------------------------------------------------+------- 3 | AB | 8 6 | BD | 7 (2 rows)
复制
通过id列,查看根据name和class两列匹配的重复列。执行如下语句删除重复数据。
postgres=# delete from test_chongfu where id not in (select min(id) from test_chongfu group by name,class); DELETE 2 postgres=# select * from test_chongfu; id | name | class ----+----------------------------------------------------+------- 1 | AA | 1 2 | AB | 8 4 | BB | 5 5 | BD | 7 (4 rows)
复制
三、不存在唯一标识情况
恢复初始测试环境。如果表里不存在唯一标识列,可以通过ctid来进行。ctid类似于oracle的rowid,但是形式不同。
postgres=# select * from test_chongfu; id | name | class ----+----------------------------------------------------+------- 1 | AA | 1 2 | AB | 8 3 | AB | 8 4 | BB | 5 5 | BD | 7 6 | BD | 7 (6 rows) postgres=# select * from test_chongfu where ctid not in( select min(ctid) from test_chongfu group by name,class); id | name | class ----+----------------------------------------------------+------- 3 | AB | 8 6 | BD | 7 (2 rows) postgres=# delete from test_chongfu where ctid not in( select min(ctid) from test_chongfu group by name,class); DELETE 2 postgres=# select * from test_chongfu; id | name | class ----+----------------------------------------------------+------- 1 | AA | 1 2 | AB | 8 4 | BB | 5 5 | BD | 7 (4 rows)
复制
四、not in优化
in本来效率就很低,not in的效率更加低,如果数据量很大的情况,可能执行时间会特别长。因此可以尝试把查询到的唯一数据重新插入到一张新表里,然后把原来旧表删掉,最后修改去重数据后的新表名为旧表名。
postgres=# create table tab_new as select * from test_chongfu where ctid in(select min(ctid) from test_chongfu group by name,class); SELECT 4 postgres=# select * from tab_new; id | name | class ----+----------------------------------------------------+------- 1 | AA | 1 2 | AB | 8 4 | BB | 5 5 | BD | 7 (4 rows)
复制
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。
评论
您好,您的文章已入选合格奖,10墨值奖励已经到账请查收!
❤️我们还会实时派发您的流量收益。
3年前

评论
相关阅读
外国CTO也感兴趣的开源数据库项目——openHalo
小满未满、
388次阅读
2025-04-21 16:58:09
9.9 分高危漏洞,尽快升级到 pgAdmin 4 v9.2 进行修复
严少安
353次阅读
2025-04-11 10:43:23
3月“墨力原创作者计划”获奖名单公布
墨天轮编辑部
331次阅读
2025-04-15 14:48:05
openHalo问世,全球首款基于PostgreSQL兼容MySQL协议的国产开源数据库
严少安
294次阅读
2025-04-07 12:14:29
postgresql+patroni+etcd高可用安装
necessary
166次阅读
2025-03-28 10:11:23
从 Oracle 到 PostgreSQL迁移成本评估揭秘
梧桐
152次阅读
2025-03-27 17:21:42
手把手教你在 openKylin 上部署 IvorySQL 4.4
严少安
150次阅读
2025-03-27 20:41:28
转发有奖 | PostgreSQL 16 PGCM高级认证课程直播班招生中!
墨天轮小教习
146次阅读
2025-04-14 15:58:34
墨天轮PostgreSQL认证证书快递已发(2025年3月批)
墨天轮小教习
126次阅读
2025-04-03 11:43:25
SQL 优化之 OR 子句改写
xiongcc
91次阅读
2025-04-21 00:08:06