J'aime la solution de @erwin-brandstetter , mais je voulais montrer une solution avec le USING
mot-clé :
DELETE FROM table_with_dups T1
USING table_with_dups T2
WHERE T1.ctid < T2.ctid -- delete the "older" ones
AND T1.name = T2.name -- list columns that define duplicates
AND T1.address = T2.address
AND T1.zipcode = T2.zipcode;
Si vous souhaitez revoir les enregistrements avant de les supprimer, remplacez simplement DELETE
avec SELECT *
et USING
avec une virgule ,
, c'est-à-dire
SELECT * FROM table_with_dups T1
, table_with_dups T2
WHERE T1.ctid < T2.ctid -- select the "older" ones
AND T1.name = T2.name -- list columns that define duplicates
AND T1.address = T2.address
AND T1.zipcode = T2.zipcode;
Mise à jour :j'ai testé certaines des différentes solutions ici pour la vitesse. Si vous ne vous attendez pas à beaucoup de doublons, alors cette solution fonctionne bien mieux que celles qui ont un NOT IN (...)
clause car celles-ci génèrent beaucoup de lignes dans la sous-requête.
Si vous réécrivez la requête pour utiliser IN (...)
alors il fonctionne de la même manière que la solution présentée ici, mais le code SQL devient beaucoup moins concis.
Mise à jour 2 :si vous avez NULL
valeurs dans l'une des colonnes clés (ce que vous ne devriez vraiment pas IMO), alors vous pouvez utiliser COALESCE()
dans la condition de cette colonne, par exemple
AND COALESCE(T1.col_with_nulls, '[NULL]') = COALESCE(T2.col_with_nulls, '[NULL]')