Say I have a table like this:
| id | grp | time_added | previous_id |
|----|-------|------------|-------------|
| 1 | 1 | 5 | null |
| 2 | 1 | 8 | null |
| 3 | 2 | 9 | null |
| 4 | 1 | 12 | null |
| 5 | 2 | 15 | null |
(time_added is actually a date, but numbers are used here for readability)
I want to update the previous_id of each row so that it's equal to the id of the previous row in the same group grp sorted by time_added.
This means that after running the update query, the table above should look like:
| id | grp | time_added | previous_id |
|----|-------|------------|-------------|
| 1 | 1 | 5 | null |
| 2 | 1 | 8 | 1 |
| 3 | 2 | 9 | null |
| 4 | 1 | 12 | 2 |
| 5 | 2 | 15 | 3 |
What I have so far is the following query:
UPDATE the_table r
SET previous_id = sub.id
FROM (
SELECT id, time_added, grp
FROM the_table
ORDER BY time_added DESC
) sub
WHERE (
r.grp = sub.grp
AND sub.time_added < r.time_added
);
However, I suspect the ORDER BY of the subquery does not do what I want it to, and the previous_id is set to the id of a random row below it, not the one strictly below it.
See this fiddle for an example of what happens. Row 3 is given a previous_id of 1, when it should be 2.