How can I execute multiple update statements for a list of id's in PostgresSQL all at once?
I have 3 UPDATE
statements (that update more than one column) that I would like to execute against a list of id's without having to run the 3 update statements one by one against each id
.
Here are the 3 update statements I need to run against a bunch of id
s:
-- store ContractDate value in temp col
update tval set temp_col = (select val from tval where id = 402280209 and fid = 3782) where id = 402280209 and fid = 3782
-- Replace ContractDate with maturityDate
update tval set val= (select val from tval where fid = 3771 and id = 402280209) where fid = 3782 and id = 402280209
-- set MaturityDate to ContactDate
update tval set val = (select temp_col from tval where id = 402280209 and fid = 3782) where id = 402280209 and fid = 3771
I have a list of id
's that I need to run the above 3 update statement against. Is it possible to run the above as a batch (i.e. in one query)?
For reference my tval
table looks something like this:
id fid ts val temp_col
402280209 3765 2021-09-20 00:00:00.000 2023-12-19 00:00:00.000
402280209 3771 2021-09-20 00:00:00.000 2023-09-20 00:00:00.000 <---- I would like to swap this value
402280209 3782 2021-09-20 00:00:00.000 2023-12-19 00:00:00.000 <----- with this value
What I am trying to avoid is running the above manually for each id
.
So my desired result is:
id fid ts val temp_col
402280209 3765 2021-09-20 00:00:00.000 2023-12-19 00:00:00.000
402280209 3771 2021-09-20 00:00:00.000 2023-12-19 00:00:00.000
402280209 3782 2021-09-20 00:00:00.000 2023-09-20 00:00:00.000
Answers
You can achieve this by combining the three update statements into a single query using conditional logic. Here's how you can do it:
WITH UpdatedValues AS (
SELECT
id,
fid,
CASE
WHEN fid = 3782 THEN (SELECT val FROM tval WHERE fid = 3771 AND tval.id = ids.id)
WHEN fid = 3771 THEN (SELECT temp_col FROM tval WHERE fid = 3782 AND tval.id = ids.id)
ELSE val
END AS new_val
FROM
tval
WHERE
id IN (/* Your list of ids */)
),
UpdatedTval AS (
UPDATE tval
SET val = uv.new_val
FROM UpdatedValues uv
WHERE tval.id = uv.id AND tval.fid = uv.fid
)
UPDATE tval
SET temp_col = uv.new_val
FROM UpdatedValues uv
WHERE tval.id = uv.id AND tval.fid = 3782;
In this query:
- The
UpdatedValues
common table expression (CTE) calculates the new values based on the conditions specified in your update statements. - The
UpdatedTval
CTE updates theval
column in thetval
table based on the calculated new values. - Finally, the last
UPDATE
statement updates thetemp_col
column in thetval
table based on the new values wherefid
is 3782.
Replace /* Your list of ids */
with the list of IDs against which you want to run these updates. This query will update all the specified IDs in one go, avoiding the need to run the updates manually for each ID.