Using TSQL, no idea if Postgres supports temp tables but you could select into a temp table, and then loop through and delete and insert your results back into the original
-- **Disclaimer** using TSQL -- You could select your records into a temp table with a pk Create Table #dupes ([id] int not null identity(1,1), f1 int, f2 int, f3 int) Insert Into #dupes (f1,f2,f3) values (1,2,3) Insert Into #dupes (f1,f2,f3) values (1,2,3) Insert Into #dupes (f1,f2,f3) values (1,2,3) Insert Into #dupes (f1,f2,f3) values (2,3,4) Insert Into #dupes (f1,f2,f3) values (4,5,6) Insert Into #dupes (f1,f2,f3) values (4,5,6) Insert Into #dupes (f1,f2,f3) values (4,5,6) Insert Into #dupes (f1,f2,f3) values (7,8,9) Select f1,f2,f3 From #dupes Declare @rowCount int Declare @counter int Set @counter = 1 Set @rowCount = (Select Count([id]) from #dupes) while (@counter < @rowCount + 1) Begin Delete From #dupes Where [Id] <> (Select [id] From #dupes where [id]=@counter) and ( [f1] = (Select [f1] from #dupes where [id]=@counter) and [f2] = (Select [f2] from #dupes where [id]=@counter) and [f3] = (Select [f3] from #dupes where [id]=@counter) ) Set @counter = @counter + 1 End Select f1,f2,f3 From #dupes -- You could take these results and pump them back into --your original table Drop Table #dupes
Tested this on MS SQL Server 2000. Not familiar with Postgres' options but maybe this will lead you in a right direction.