PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

So löschen Sie doppelte Zeilen ohne eindeutige Kennung

Ich mag die Lösung von @erwin-brandstetter , wollte aber eine Lösung mit dem USING zeigen Stichwort:

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;

Wenn Sie die Datensätze vor dem Löschen überprüfen möchten, ersetzen Sie einfach DELETE mit SELECT * und USING mit einem Komma , , also

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;

Update:Ich habe einige der verschiedenen Lösungen hier auf Geschwindigkeit getestet. Wenn Sie nicht viele Duplikate erwarten, ist diese Lösung viel besser als die mit NOT IN (...) -Klausel, da diese viele Zeilen in der Unterabfrage generieren.

Wenn Sie die Abfrage so umschreiben, dass sie IN (...) verwendet dann verhält es sich ähnlich wie die hier vorgestellte Lösung, aber der SQL-Code wird viel weniger prägnant.

Update 2:Wenn Sie NULL haben Werte in einer der Schlüsselspalten (was Sie meiner Meinung nach wirklich nicht sollten), dann können Sie COALESCE() verwenden in der Bedingung für diese Spalte, z. B.

  AND COALESCE(T1.col_with_nulls, '[NULL]') = COALESCE(T2.col_with_nulls, '[NULL]')