PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Comment supprimer des lignes en double sans identifiant unique

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]')