Líbí se mi řešení @erwin-brandstetter , ale chtěl jsem ukázat řešení pomocí USING
klíčové slovo:
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;
Pokud chcete záznamy před smazáním zkontrolovat, jednoduše nahraďte DELETE
pomocí SELECT *
a USING
s čárkou ,
, tj.
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;
Aktualizace:Testoval jsem zde některá různá řešení pro rychlost. Pokud neočekáváte mnoho duplikátů, pak toto řešení funguje mnohem lépe než ty, které mají NOT IN (...)
klauzule, protože tyto generují mnoho řádků v poddotazu.
Pokud dotaz přepíšete tak, aby používal IN (...)
pak funguje podobně jako zde uvedené řešení, ale kód SQL je mnohem méně stručný.
Aktualizace 2:Pokud máte NULL
hodnoty v jednom z klíčových sloupců (což byste IMO opravdu neměli), pak můžete použít COALESCE()
ve stavu pro tento sloupec, např.
AND COALESCE(T1.col_with_nulls, '[NULL]') = COALESCE(T2.col_with_nulls, '[NULL]')