Try something like:
WITH
new_data (id, value) AS (
VALUES (1, 2), (3, 4), ...
),
updated AS (
UPDATE table t set
value = t.value + new_data.value
FROM new_data
WHERE t.id = new_data.id
RETURNING t.*
),
inserted as (
INSERT INTO table (id, value)
SELECT id, value
FROM new_data
WHERE NOT EXISTS (
SELECT 1 FROM updated WHERE updated.id = new_data.id
)
RETURNING id, value)
SELECT id, value
FROM inserted
UNION ALL
SELECT id, value
FROM updated
BTW this query is not a classical Postgres upsert. It will fail, if someone concurrently insert rows while UPDATE table t
is going.