ctidを使用してそれを実現できます。例えば:
重複するテーブルを作成します。
=# create table foo (id1 integer, id2 integer);
CREATE TABLE
=# insert into foo values (1,1), (1, 2), (1, 2), (1, 3);
INSERT 0 4
=# select * from foo;
id1 | id2
-----+-----
1 | 1
1 | 2
1 | 2
1 | 3
(4 rows)
重複するデータを選択します。
=# select foo.ctid, foo.id1, foo.id2, foo2.min_ctid
-# from foo
-# join (
-# select id1, id2, min(ctid) as min_ctid
-# from foo
-# group by id1, id2
-# having count (*) > 1
-# ) foo2
-# on foo.id1 = foo2.id1 and foo.id2 = foo2.id2
-# where foo.ctid <> foo2.min_ctid ;
ctid | id1 | id2 | min_ctid
-------+-----+-----+----------
(0,3) | 1 | 2 | (0,2)
(1 row)
重複するデータを削除します。
=# delete from foo
-# where ctid not in (select min (ctid) as min_ctid from foo group by id1, id2);
DELETE 1
=# select * from foo;
id1 | id2
-----+-----
1 | 1
1 | 2
1 | 3
(3 rows)
あなたの場合、以下がうまくいくはずです:
delete from questions_tags
where ctid not in (
select min (ctid) as min_ctid
from questions_tags
group by question_id, tag_id
);