PostgreSQL 更新自

Jul*_*sch 3 postgresql temp-tables sql-update

如果这个问题已经在其他地方得到了回答,我深表歉意,恐怕我需要对 PostgreSQL 中的 UPDATE FROM 子句进行更多的澄清/整理。

基本上我有一个临时表,其中包含一些中间计算的内容,我想用它们来更新主表。这个临时表包含两个外键和一个分数,例如:

score   fk_offer    fk_searchprofile
65      1764        12345
...
Run Code Online (Sandbox Code Playgroud)

我测试了要使用选择更新的行(该表temp_offerids_with_score包含需要更新的报价):

SELECT s.pkid, tmp.fk_offer, s.fk_category, tmp.score, tmp.fk_searchprofile
FROM 
            temp_weighted_scores_offers AS tmp
            INNER JOIN sc_sp_o_c_score AS s
            ON tmp.fk_offer = s.fk_offer
WHERE 
            tmp.fk_offer IN (SELECT fk_offer FROM temp_offerids_with_score)
            AND 
            s.fk_category = 1
            AND s.fk_searchprofile = 12345;
Run Code Online (Sandbox Code Playgroud)

这将正确返回预期的行数(在本例中为 10):

pkid    fk_offer    fk_category  score  fk_searchprofile
1       47          1            78     12345
2       137         1            64     12345
3       247         1            50     12345
...
Run Code Online (Sandbox Code Playgroud)

但是,如果我在 UPDATE FROM 中使用相同的内容:

UPDATE sc_sp_o_c_score
      SET score = tmp.score
FROM 
            temp_weighted_scores_offers AS tmp
            INNER JOIN sc_sp_o_c_score AS s
            ON tmp.fk_offer = s.fk_offer
WHERE 
            tmp.fk_offer IN (SELECT fk_offer FROM temp_offerids_with_score)
            AND 
            s.fk_category = 1
            AND s.fk_searchprofile = 12345;
Run Code Online (Sandbox Code Playgroud)

整个表(超过 32000 行)会以相同的总体分数(当然是错误的)进行更新。

pkid    fk_offer    fk_searchprofile    fk_category score
1       47          12345               1           104 
2       137         12345               1           104
3       247         12345               1           104
Run Code Online (Sandbox Code Playgroud)

我缺少什么?

谢谢,朱利安

编辑:以防万一这可能有任何帮助 - 作为记录,我正在从 SQL Server 迁移内容,这实际上是一个有效的构造。

Pat*_*ick 5

您还使用要更新的表作为自联接(通过FROM子句中的引用)。把它拿出来,你应该会很好:

UPDATE sc_sp_o_c_score
  SET score = tmp.score
  FROM temp_weighted_scores_offers AS tmp
  WHERE tmp.fk_offer = fk_offer
    AND tmp.fk_offer IN (SELECT fk_offer FROM temp_offerids_with_score)
    AND fk_category = 1
    AND fk_searchprofile = 12345;
Run Code Online (Sandbox Code Playgroud)