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