1

我需要获取表中重复行的 id 列表,以便可以使用where id in. 这是我的桌子:

id|col1|col2
1 |22  | text
2 |22  | text
3 |23  | text
4 |22  | text2

所以在这里 ids12是重复的,其他不是。所以我知道如何通过使用来获得它们group by and having count(*) > 1

但我想保留一个并删除其他的。所以这就是清除重复项后该表的样子:

    id|col1|col2
    1 |22  | text
    3 |23  | text
    4 |22  | text2

或者 :

id|col1|col2
2 |22  | text
3 |23  | text
4 |22  | text2

任何一个都可以。我怎样才能做到这一点?摆脱重复项,但最后保留其中一个重复项,使其不再重复?

我的下一个目标是为这些字段添加索引,这样就不会再发生这种情况了。

4

3 回答 3

3

尝试类似:

delete from table_name
where id not in (select min(id)
                 from table_name
                 group by col1, col2);

它将删除id每个col1, col2组中非最小的所有行。

替代查询:

delete from table_name t1
where exists (select *
              from table_name t2
              where t1.col1 = t2.col2
                and t1.col2 = t2.col2
                and t1.id < t2.id );

它做同样的事情,只是以其他方式。

于 2013-09-18T13:57:35.583 回答
0

Igor Romanchenko 给出了很好的解决方案,另一个可能是:

with cte as c (
    select id, row_number() over(partition by col1, col2 order by id) as rn
    from Table1
)
delete Table1 as t
from cte as c
where c.id = t.id and c.rn > 1
于 2013-09-18T14:10:55.447 回答
0

我觉得这个可能会慢一点

DELETE FROM tab
NATURAL JOIN 
(
   SELECT DISTINCT ON(col2, col3) id AS target, col2, col3
   FROM tab
   ORDER by col2, col3 /* can add order by id if you care which is kept */
) AS subq WHERE tab.id <> subq.target; 

但我会在样本数据上尝试一下。

于 2013-09-18T15:41:20.823 回答