There is table in postgres db:
event_stats_table
id: pk int
rank: int
rank_delta: int
event_id: int
user_id: int
Every record saves user position for every event.
I am trying to write a query which would update rank_delta
fields for all users in comparing with the previous event_id. If previous event_id is null – write 0.
Current and previous id are known, I do not need to update data between every event, only selected pair.
For example I need to update deltas between event_id=1
and event_id=2
and write data into event_id=2
row and tried following sql:
update event_stats_table
set rank_delta = st1.rank - coalesce(st2.rank, st1.rank_delta)
from event_stats_table st1
left outer join event_stats_table st2 on st1.user_id = st2.user_id and st2.event_id = 1
where st1.event_id = 2;
But this event updates both records instead of st1
only. I tried to put st1
in the first line of sql and got syntax errors, because st1 is not known at that moment.
I appreciate any advises on this case or even better solutions which are no doubt exist, thx.
UPD 1 changed grand_prix_id
to event_id
everywhere
UPD 2 Adding sample datum:
Before:
id | rank | rank_delta | event_id | user_id |
---|---|---|---|---|
1 | 1 | 0 | 1 | 1 |
2 | 5 | 0 | 2 | 1 |
After:
id | rank | rank_delta | event_id | user_id |
---|---|---|---|---|
1 | 1 | 0 | 1 | 1 |
2 | 5 | -4 | 2 | 1 |
2
Answers
that is something weird about handling such self joins in Postgres, but you can do
fiddle
Where you’re going wrong is that the table to updated is already available for referencing columns and is effectively joined to the tables listed in the
FROM
part of the statement. In your case the tables listed in yourFROM
don’t change their results depending on which row of the table to be updated is being evaluated. See the UPDATE syntax docs for more information.One way to address this would be something like: