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

Sådan sletter du dublerede rækker uden entydig identifikator

Jeg kan godt lide @erwin-brandstetters løsning, men ville gerne vise en løsning med USING søgeord:

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;

Hvis du vil gennemgå posterne, før du sletter dem, skal du blot erstatte DELETE med SELECT * og USING med et komma , , dvs.

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;

Opdatering:Jeg testede nogle af de forskellige løsninger her for hastighed. Hvis du ikke forventer mange dubletter, så yder denne løsning meget bedre end dem, der har en NOT IN (...) klausul, da disse genererer mange rækker i underforespørgslen.

Hvis du omskriver forespørgslen til at bruge IN (...) så fungerer den på samme måde som den her præsenterede løsning, men SQL-koden bliver meget mindre kortfattet.

Opdatering 2:Hvis du har NULL værdier i en af ​​nøglekolonnerne (som du egentlig ikke burde IMO), så kan du bruge COALESCE() i tilstanden for den kolonne, f.eks.

  AND COALESCE(T1.col_with_nulls, '[NULL]') = COALESCE(T2.col_with_nulls, '[NULL]')


  1. En biblioteksdatamodel

  2. Oversættelse af Salesforce-data til EDI-format

  3. Sådan vises en dato i tysk format i SQL Server (T-SQL)

  4. Find ud af, om en partition er komprimeret i SQL Server (T-SQL)