0

I have a postgresql table without primary key. I want to remove all entries that have the same id, but retain the most recent one.

The following statement almost works:

DELETE FROM mytable USING mytable t
  WHERE mytable.id = t.id AND mytable.modification < t.modification;

Problem: when two entries have the same modification timestamp (which is possible), both are retained. What would I have to change to just keep one of them, does not matter which one?

I cannot change the condition to AND mytable.modification <= t.modification; as this would then remove all dublicates not retaining any entry.

2 Answers 2

2

If you have rows that are complete duplicates (i.e., no way to distinguish one from the other), then you have two options. One is to use a built-in row identifier such as ctid:

DELETE FROM mytable USING mytable t
  WHERE mytable.id = t.id AND
        (mytable.modification < t.modification OR
         mytable.modification = t.modification AND mytable.ctid < t.ctid);

Or use a secondary table:

create table tokeep as
    select distinct on (t.id) t.*
    from mytable
    order by t.id, t.modification;

truncate table mytable;

insert into mytable
    select * from tokeep;
Sign up to request clarification or add additional context in comments.

Comments

0

Use EXISTS to see if there are other rows with same id:

DELETE FROM mytable t
WHERE EXISTS (SELECT 1 from mytable
              WHERE id = t.id AND modification > t.modification);

4 Comments

I tried it but 0 rows where affected in a table with 2 entries having exactly the same id and modification timestamp. But one of them should get deleted.
It's hard to remove just one of two equal rows. Move to temp-table using select distinct?
Could I tell the select distinct(id) to fetch the most recent row with the latest modification stamp?
See Gordon Linoff's answer above.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.