Me gusta la solución de @erwin-brandstetter, pero quería mostrar una solución con USING
palabra clave:
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 desea revisar los registros antes de eliminarlos, simplemente reemplace DELETE
con SELECT *
y USING
con coma ,
, es decir,
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;
Actualización:probé algunas de las diferentes soluciones aquí para la velocidad. Si no espera muchos duplicados, entonces esta solución funciona mucho mejor que las que tienen un NOT IN (...)
cláusula ya que generan muchas filas en la subconsulta.
Si reescribe la consulta para usar IN (...)
entonces funciona de manera similar a la solución presentada aquí, pero el código SQL se vuelve mucho menos conciso.
Actualización 2:si tiene NULL
valores en una de las columnas clave (que en realidad no deberías IMO), entonces puedes usar COALESCE()
en la condición de esa columna, por ejemplo,
AND COALESCE(T1.col_with_nulls, '[NULL]') = COALESCE(T2.col_with_nulls, '[NULL]')