Mi piace la soluzione di @erwin-brandstetter, ma volevo mostrare una soluzione con USING
parola chiave:
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;
Se desideri rivedere i record prima di eliminarli, sostituisci semplicemente DELETE
con SELECT *
e USING
con una virgola ,
, cioè
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;
Aggiornamento:ho testato alcune delle diverse soluzioni qui per la velocità. Se non ti aspetti molti duplicati, questa soluzione funziona molto meglio di quelle che hanno un NOT IN (...)
clausola in quanto generano molte righe nella sottoquery.
Se riscrivi la query per utilizzare IN (...)
quindi si comporta in modo simile alla soluzione qui presentata, ma il codice SQL diventa molto meno conciso.
Aggiornamento 2:se hai NULL
valori in una delle colonne chiave (che in realtà non dovresti IMO), quindi puoi usare COALESCE()
nella condizione per quella colonna, ad es.
AND COALESCE(T1.col_with_nulls, '[NULL]') = COALESCE(T2.col_with_nulls, '[NULL]')