Çoğaltılacak alanlarda aynı tabloya katılabilir ve ardından id alanında anti-join yapabilirsiniz. İlk tablo diğer adından (tn1) id alanını seçin ve ardından ikinci tablo diğer adının id alanındaki array_agg işlevini kullanın. Son olarak, array_agg işlevinin düzgün çalışması için sonuçları tn1.id alanına göre gruplandırırsınız. Bu, bir kaydın kimliğini ve birleştirme koşullarına uyan tüm kimliklerin bir dizisini içeren bir sonuç kümesi oluşturur.
select tn1.id,
array_agg(tn2.id) as duplicate_entries,
from table_name tn1 join table_name tn2 on
tn1.year = tn2.year
and tn1.sid = tn2.sid
and tn1.user_id = tn2.user_id
and tn1.cid = tn2.cid
and tn1.id <> tn2.id
group by tn1.id;
Açıkçası, bir kimlik için duplicate_entries dizisinde yer alacak id'lerin sonuç kümesinde kendi girişleri de olacaktır. Hangi sonucun 'gerçeğin' kaynağı olmasını istediğinize karar vermek için bu sonuç kümesini kullanmanız gerekecektir. Silinmemesi gereken tek kayıt. Belki böyle bir şey yapabilirsiniz:
with dupe_set as (
select tn1.id,
array_agg(tn2.id) as duplicate_entries,
from table_name tn1 join table_name tn2 on
tn1.year = tn2.year
and tn1.sid = tn2.sid
and tn1.user_id = tn2.user_id
and tn1.cid = tn2.cid
and tn1.id <> tn2.id
group by tn1.id
order by tn1.id asc)
select ds.id from dupe_set ds where not exists
(select de from unnest(ds.duplicate_entries) as de where de < ds.id)
Kopyaları olan en düşük sayı ID'lerini seçer (ID'nin PK'da arttığı varsayılarak). Bunlar etrafta saklayacağınız kimliklerdir.