简体   繁体   中英

PostgreSQL can't UPSERT with a “WITH”

I want to upsert a value with a WITH, like this:

WITH counted as (
   SELECT votant, count(*) as nbvotes
    FROM votes
    WHERE votant = '123456'
    GROUP BY votant
)

INSERT INTO badges(id, badge, conditions, niveau, date_obtention)
VALUES('123456', 'category', c.nbvotes, 1, current_timestamp)
ON CONFLICT (id, badge)
DO UPDATE badges b
SET b.conditions = c.nbvotes
FROM counted c
WHERE b.id = c.votant AND b.badge = 'category'

The console tells me I have an error on " badges " just after " DO UPDATE " I really don't understand what goes wrong here, if anybpdy could give me a hand, it would be great :)

As documented in the manual the badges b after the do update part is wrong - and unnecessary if you think of it. The target table is already defined by the INSERT part.

But you also don't need a FROM or join to the original value.

So just use:

...
ON CONFLICT (id, badge)
DO UPDATE 
  SET conditions = '{"a":"loooool"}';

If you need to access the original values, you can use the excluded record to refer to it, eg

  SET conditions = EXCLUDED.conditions

which in your case would refer to the rows provided in the values clause ( {"a":"lol"}' in your example)

And target columns of an UPDATE cannot be table-qualified. So just SET conditions = ...


If you want to use the result of the CTE as the source of the INSERT, you need to use an INSERT ... SELECT . You can't use a FROM clause in the DO UPDATE part of an INSERT.

WITH counted as (
  SELECT votant, count(*) as nbvotes
  FROM votes
  WHERE votant = '123456'
  GROUP BY votant
)
INSERT INTO badges(id, badge, conditions, niveau, date_obtention)
SELECT '123456', 'category', c.nbvotes, 1, current_timestamp
FROM counted c
ON CONFLICT (id, badge)
DO UPDATE 
   SET conditions = excluded.conditions

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM