This will keep one of the duplicates:
delete from join_table
where ctid not in (select min(ctid)
from join_table
group by id1, id2);
Your table doesn't have a unique identifier that could be used to "pick one survivor". That's where Postgres' ctid
comes in handy, as it is an internal unique identifier for each row. Note that you should never use the ctid
for more than just a single statement. It is not a universally unique things but for the runtime of a single statement it's just fine.
SQLFiddle example: http://sqlfiddle.com/#!15/dabfc/1
If you want to get rid of all rows that are duplicated:
delete from join_table
where (id1, id2) in (select id1, id2
from join_table
group by id1, id2
having count(*) > 1);
Neither solution will be fast on a large table. Creating a new table without duplicates as jjanes has shown will be much faster if you need a substantial number of rows from a large table.