postgresql Postgres更新增量

kninwzqo  于 2023-06-22  发布在  PostgreSQL
关注(0)|答案(2)|浏览(200)

postgres db中有一个表:

event_stats_table

id: pk int
rank: int
rank_delta: int
event_id: int
user_id: int

每个记录保存每个事件的用户位置。
我正在尝试编写一个查询,它将更新所有用户的rank_delta字段,与以前的event_id进行比较。如果前一个event_id为空-写入0。
当前和以前的id是已知的,我不需要更新每个事件之间的数据,只需要选择对。
例如,我需要更新event_id=1event_id=2之间的增量,并将数据写入event_id=2行,并尝试以下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;

但此事件更新两个记录,而不是仅更新st1。我试着把st1放在sql的第一行,得到了语法错误,因为st 1在那一刻是未知的。
我很感激任何关于这个案子的建议,甚至更好的解决方案,这是毫无疑问存在的,thx。

UPD 1grand_prix_id全部更改为event_id
UPD 2添加样品数据:之前:

| id|秩|秩差|事件ID|用户id|
| - -----|- -----|- -----|- -----|- -----|
| 1| 1| 0| 1| 1|
| 2| 5个|0| 2| 1|
之后:
| id|秩|秩差|事件ID|用户id|
| - -----|- -----|- -----|- -----|- -----|
| 1| 1| 0| 1| 1|
| 2| 5个|-4| 2| 1|

nkkqxpd9

nkkqxpd91#

在Postgres中处理这样的自连接有些奇怪,但你可以这样做。

CREATE TABLE event_stats_table(

id int,
points int,
rank int,
rank_delta int,
event_id int,
user_id int,
  grand_prix_id int)
CREATE TABLE
INSERT INTO event_stats_table VALUES( 1,1,2,1,1,1,1), ( 1,1,1,1,2,1,2)
INSERT 0 2
WITH st2 as (
   SELECT 
user_id as user_id2,
  rank as rank2,
  event_id as event_id2 FROM  event_stats_table)
update event_stats_table  st1
set rank_delta = rank - coalesce(st2.rank2, rank_delta)
from  st2 
  WHERE st1.user_id = st2.user_id2 and st2.event_id2 = 1
    AND  st1.event_id = 2;
UPDATE 1
SELECT * FROM event_stats_table

| id|点|秩|秩差|事件ID|用户id|大奖赛ID|
| - -----|- -----|- -----|- -----|- -----|- -----|- -----|
| 1| 1| 2| 1| 1| 1| 1|
| 1| 1| 1|-1| 2| 1| 2|

SELECT 2

fiddle

2nbm6dog

2nbm6dog2#

错误的地方在于,要更新的表已经可以引用列,并且实际上与语句的FROM部分中列出的表联接。在您的示例中,FROM中列出的表不会根据要更新的表的哪一行被评估而改变其结果。有关详细信息,请参阅the UPDATE syntax docs
解决这个问题的一种方法是:

update event_stats_table est
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.grand_prix_id = 1
    where st1.grand_prix_id = 2 and est.id = st1.id;

相关问题