sql >> Base de Datos >  >> RDS >> PostgreSQL

Cómo eliminar filas duplicadas sin identificador único

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