Voici une solution en utilisant PARTITION BY
et le virtuel ctid
colonne qui fonctionne comme une clé primaire, du moins au sein d'une même session :
DELETE FROM dups
USING (
SELECT
ctid,
(
ctid != min(ctid) OVER (PARTITION BY key_column1, key_column2 [...])
) AS is_duplicate
FROM dups
) dups_find_duplicates
WHERE dups.ctid == dups_find_duplicates.ctid
AND dups_find_duplicates.is_duplicate
Une sous-requête est utilisée pour marquer toutes les lignes comme dupliquées ou non, en fonction du fait qu'elles partagent les mêmes "colonnes clés", mais pas les mêmes ctid
comme la "première" trouvée dans la "partition" des lignes partageant les mêmes clés.
En d'autres termes, le terme "premier" est défini comme suit :
min(ctid) OVER (PARTITION BY key_column1, key_column2 [...])
Ensuite, toutes les lignes où is_duplicate
est vrai sont supprimés par leur ctid
.
Extrait de la documentation, ctid
représente ( l'accent mine) :
Emplacement physique de la version de la ligne dans sa table. Notez que bien que le ctid puisse être utilisé pour localiser très rapidement la version de la ligne Le ctid d'une ligne changera si elle est mise à jour ou déplacée par VACUUM FULL. Par conséquent, le ctid est inutile en tant qu'identifiant de ligne à long terme. Une clé primaire doit être utilisée pour identifier les lignes logiques.