PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Come eliminare le righe duplicate senza identificatore univoco

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