Reputation: 1072
I'm needing to update multiple rows in the same sql transaction using PostgreSQL. From the post below: Update multiple rows in same query using PostgreSQL I see the following code:
UPDATE test AS t SET
column_a = c.column_a,
column_c = c.column_c
FROM (values
(123, 1, '---'),
(345, 2, '+++')
) AS c(column_b, column_a, column_c)
WHERE c.column_b = t.column_b;
BUT, this is only if you are updating all columns for each set of values, in which I'm not. Does anyone have a solution to this to allow multiple updates use just SQL alone (not plpgsql)?
Upvotes: 0
Views: 277
Reputation: 1269503
Assuming you are not updating to NULL
values, you could use:
UPDATE test t
SET column_a = COALESCE(c.column_a, t.column_a),
column_c = COALESCE(c.column_c, t.column_c
FROM (values ('123', 1, NULL),
('345', NULL, '+++')
) c(column_b, column_a, column_c)
WHERE c.column_b = t.column_b;
EDIT:
If the values can be NULL
, then you need additional columns to specify if the value should be used:
UPDATE test t
SET column_a = (CASE WHEN c.use_a THEN c.column_a::numeric ELSE t.column_a END),
column_c = (CASE WHEN c.use_b THEN c.column_c::varchar ELSE t.column_c END)
FROM (values (123, 1, NULL, true, false),
(345, NULL, '+++', false true)
) c(column_b, column_a, column_c, use_a, use_c)
WHERE c.column_b::int4 = t.column_b;
Upvotes: 2
Reputation: 14861
Your contention "this is only if you are updating all columns for each set of values" is incorrect. The update will effect only those columns mentioned in the SET clause. Since you accept NULL as new values then just a straight set for the specific columns:
update test t
set column_a = c.column_a
, column_c = c.column_c
from (values ('123', 1, NULL, 'Ignored Column')
, ('345', NULL, '+++','Ignored Column')
) c(column_b, column_a, column_c,column_d)
where c.column_b = t.column_b ;
See fiddle, particularly the additional column_d.
Upvotes: -1