今天写一个查询,需要查询表内某两列重复的数据,随之想到了删除重复行。这个在前几年的被面试中,也被提问过。做面试官的时候也问过别人。 算是一个比较基础的内容吧。 如果需要查询数据,只需要将列分组(group by),对查询结果做计数(count),大于1的就是重复的行,
如何删除重复行: Oracle中,众所周知,存在一个虚拟列叫做row_num,我们可以删除小的或者大的row_num,这样,就只保留了一个。 那PG中呢,PG中也有一个虚拟列,叫做ctid,同样,我们可以删除大的或者小的ctid,只保留一个。
看SQL最直观,直接上SQL: 环境PG 11 beta 3:
test=# select * from test1031; id | col1 | col2 | col3 ----+------+------+------ 1 | a | b | c 1 | a | a | c 2 | a | b | c 1 | a | b | c 3 | c | c | c (5 rows)
查询表内col1, col2, col3 重复的行 test=# select col1, col2, col3, count(*) from test1031 group by col1, col2, col3 having count(*) > 1; col1 | col2 | col3 | count ------+------+------+------- a | b | c | 3 (1 row)
查询表内id, col1, col2, col3 重复的行 test=# select id, col1, col2, col3, count(*) from test1031 group by id, col1, col2, col3 having count(*) > 1; id | col1 | col2 | col3 | count ----+------+------+------+------- 1 | a | b | c | 2 (1 row)
那我们删除重复的行。 查询要删除的行 test=# select * from test1031 where ctid not in (select max(ctid) from test1031 group by id, col1, col2, col3); id | col1 | col2 | col3 ----+------+------+------ 1 | a | b | c (1 row)
删除 test=# delete from test1031 where ctid not in (select max(ctid) from test1031 group by id, col1, col2, col3); DELETE 1
查看重复行: test=# select id, col1, col2, col3, count(*) from test1031 group by id, col1, col2, col3 having count(*) > 1; id | col1 | col2 | col3 | count ----+------+------+------+------- (0 rows)
|
|