如何进行 PostgreSQL 条件内连接更新

How to make a PostgreSQL conditional inner join update

UPDATE "users" SET "reliabilityScore"= ( CASE WHEN r."score" < 0 THEN 0 
                                              WHEN r."score" > 100 THEN 100
                                              ELSE r."score"
END
 ) FROM "users" u, "scores" r WHERE u."id"=r."user_id";

这是我的查询。用户 table 上的所有 reliabilityScore 字段都由分数 table 上的第一个分数记录更新。

我正在尝试通过内部联接更新 Postgres 列。如果目标值小于 0,则将更新值设置为 0,如果目标值超过 100,则将更新值设置为 100,如果在 0 到 100 之间,则设置传入值。但是我的查询仅按第一个值更新所有记录。

不要在 FROM 子句中使用 users table,如下所示:

UPDATE "users" 
   SET "reliabilityScore"= CASE WHEN r."score" < 0 THEN 0 
                                WHEN r."score" > 100 THEN 100 
                           ELSE r."score" END 
FROM "scores" r WHERE u."id"=r."user_id"

Postgres 和 SQL 服务器使用看起来与 updates 相似的语法。然而,有一个关键的区别。在 Postgres 中,UPDATE 中的 table 引用 alwaysFROM 中的 table 引用分开。

换句话说,您的查询对 users 有两个单独的引用,这实际上描述了两个 table 之间的笛卡尔积。

您可以轻松解决此问题:

UPDATE users u
    SET reliabilityScore = ( CASE WHEN s.score < 0 THEN 0 
                                  WHEN s.score > 100 THEN 100
                                  ELSE s.score
                             END)
FROM scores s
WHERE s.user_id = u.id;

请注意,我从标识符名称中删除了双引号。在您重建数据库之前,这可能不会起作用。但是不要创建带有转义名称的 table。转义字符只会让查询更难编写和阅读。

如果你愿意,你也可以将“限制”操作表达为:

    SET reliabilityScore = LEAST(GREATEST(s.core, 0), 100)