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";
That is my query. And all the reliabilityScore field on users table get updated by the first score record on scores table.
I'm trying to update a Postgres column by an inner join. and set updated value to 0 if target value is less than 0, and 100 if it's over 100, and set incoming value, if between 0 and 100. But my query only updates all the records by the first value.
Don't use users
table in the FROM
clause as follows:
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 and SQL Server use what looks like similar syntax for update
s. However, there is a crucial difference. In Postgres, the table reference in the UPDATE
is always separate from the table reference in the FROM
.
In other words, your query has two separate references for users
, which actually describes a Cartesian product between the two tables.
You can easily fix this:
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;
Note that I removed the double quotes from the identifier names. This probably won't work until you rebuild your database. But don't create tables with escaped names. The escape characters just make queries harder to write and to read.
If you like, you can also express the "limiting" operation as:
SET reliabilityScore = LEAST(GREATEST(s.core, 0), 100)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.