Харесвам решението на @erwin-brandstetter, но исках да покажа решение с USING
ключова дума:
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;
Ако искате да прегледате записите, преди да ги изтриете, просто заменете DELETE
с SELECT *
и USING
със запетая ,
, т.е.
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;
Актуализация:Тествах някои от различните решения тук за скорост. Ако не очаквате много дубликати, тогава това решение работи много по-добре от тези, които имат NOT IN (...)
клауза, тъй като те генерират много редове в подзаявката.
Ако пренапишете заявката, за да използвате IN (...)
след това работи подобно на представеното тук решение, но SQL кодът става много по-малко сбит.
Актуализация 2:Ако имате NULL
стойности в една от ключовите колони (които наистина не трябва IMO), тогава можете да използвате COALESCE()
в условието за тази колона, напр.
AND COALESCE(T1.col_with_nulls, '[NULL]') = COALESCE(T2.col_with_nulls, '[NULL]')