如何进行 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 服务器使用看起来与 update
s 相似的语法。然而,有一个关键的区别。在 Postgres 中,UPDATE
中的 table 引用 always 与 FROM
中的 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)
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 服务器使用看起来与 update
s 相似的语法。然而,有一个关键的区别。在 Postgres 中,UPDATE
中的 table 引用 always 与 FROM
中的 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)