peiyuan1030 发表于 2016-11-21 09:26:55

PostgreSQL删除重复数据

  去重的方法一般是找到重复数据中的一条,以某一唯一条件去掉其他重复值。
  Oracle 去重的方法很多,常用的是根据 rowid 进行去重。
  PostgreSQL 库如何去除单表重复数据呢?可以通过 ctid 进行,下面是实验过程。

  一、创建测试表



david=# create table emp (
david(# id int,
david(# name varchar);
CREATE TABLE
david=#
  二、插入测试数据



david=# insert into emp values (1, 'david');
INSERT 0 1
david=# insert into emp values (1, 'david');
INSERT 0 1
david=# insert into emp values (1, 'david');
INSERT 0 1
david=# insert into emp values (2, 'sandy');
INSERT 0 1
david=# insert into emp values (2, 'sandy');
INSERT 0 1
david=# insert into emp values (3, 'renee');
INSERT 0 1
david=# insert into emp values (4, 'jack');
INSERT 0 1
david=# insert into emp values (5, 'rose');
INSERT 0 1
david=#
  三、查询初始化数据



david=# select ctid, * from emp;
ctid| id | name
-------+----+-------
(0,1) |1 | david
(0,2) |1 | david
(0,3) |1 | david
(0,4) |2 | sandy
(0,5) |2 | sandy
(0,6) |3 | renee
(0,7) |4 | jack
(0,8) |5 | rose
(8 rows)
david=#
  查询重复数据数



david=# select distinct id, count(*) from emp group by id having count(*) > 1;
id | count
----+-------
1 |   3
2 |   2
(2 rows)
david=#
  查询出 id 为1的记录有3条,id 为2的记录有2条。
  四、查询要保留的数据
  以 min(ctid) 或 max(ctid) 为准。



david=# select ctid, * from emp where ctid in (select min(ctid) from emp group by id);
ctid| id | name
-------+----+-------
(0,1) |1 | david
(0,4) |2 | sandy
(0,6) |3 | renee
(0,7) |4 | jack
(0,8) |5 | rose
(5 rows)
david=#
  五、删除重复数据



david=# delete from emp where ctid not in (select min(ctid) from emp group by id);
DELETE 3
david=#
  六、查看最后结果



david=# select ctid, * from emp;
ctid| id | name
-------+----+-------
(0,1) |1 | david
(0,4) |2 | sandy
(0,6) |3 | renee
(0,7) |4 | jack
(0,8) |5 | rose
(5 rows)
david=#
  说明:如果表中已经有标明唯一的序列主键值,可以把该值替换上述的ctid直接删除。
  七、其他方法
  也可以使用以下SQL删除重复数据。



david=# delete from emp a
david-# where a.ctid <>
david-# (
david(# select min(b.ctid) from emp b
david(# where a.id = b.id
david(# );
DELETE 3
david=#
  说明:在表数据量较大的情况下,这种删除方法效率很高。
页: [1]
查看完整版本: PostgreSQL删除重复数据