Assuming (like your sample data suggests):
There can never be the same id
with true
and false
in the set. Else, you'd have to define what to do.
null
values remain unchanged if there is no non-null value for the same id
.
This should give you best performance:
UPDATE tbl t
SET flag = t1.flag
FROM (
SELECT DISTINCT ON (id)
id, flag
FROM tbl
ORDER BY id, flag
) t1 -- avoid repeated computation for same id
WHERE t.id = t1.id
AND t.flag IS NULL -- avoid costly no-op updates
AND t1.flag IS NOT NULL; -- avoid costly no-op updates;
db<>fiddle here
The subquery t1
distills target values per id once.
SELECT DISTINCT ON (id)
id, flag
FROM tbl
ORDER BY id, flag;
Since null
sorts last, it effectively grabs the first non-null value per id
. false
sorts before true
, but that has no bearing on the case as there can never be both for the same id
. See:
If you have many rows per id
, there are faster techniques:
The added conditions in the outer query prevent all no-op updates from happening, thus avoiding major cost. Only rows are updated where a null
value actually changes. See: