PostgreSQL - CTE upsert returning modified rows PostgreSQL - CTE upsert returning modified rows sql sql

PostgreSQL - CTE upsert returning modified rows


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, valueFROM inserted UNION ALLSELECT id, valueFROM updated 

BTW this query is not a classical Postgres upsert. It will fail, if someone concurrently insert rows while UPDATE table t is going.