Sie können in den Feldern, die dupliziert werden sollen, derselben Tabelle beitreten und dann im ID-Feld eine Anti-Verknüpfung durchführen. Wählen Sie das ID-Feld aus dem ersten Tabellenalias (tn1) aus und verwenden Sie dann die Funktion array_agg für das ID-Feld des zweiten Tabellenalias. Damit die Funktion array_agg ordnungsgemäß funktioniert, gruppieren Sie die Ergebnisse nach dem Feld tn1.id. Dadurch wird eine Ergebnismenge erstellt, die die ID eines Datensatzes und ein Array aller IDs enthält, die den Verknüpfungsbedingungen entsprechen.
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;
Offensichtlich haben IDs, die sich für eine ID im Array duplicate_entries befinden, auch eigene Einträge in der Ergebnismenge. Sie müssen diese Ergebnismenge verwenden, um zu entscheiden, welche ID Sie zur Quelle der 'Wahrheit' werden möchten. Der eine Datensatz, der nicht gelöscht werden sollte. Vielleicht könnten Sie so etwas tun:
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)
Wählt die IDs mit der niedrigsten Anzahl aus, die Duplikate aufweisen (vorausgesetzt, die ID erhöht sich in PK). Dies wären die IDs, die Sie behalten würden.