简体   繁体   中英

PostgreSQL WITH query, execution order

I'm trying to update/delete from a table, then return the updated data via an inner join like this:

WITH removed AS (
  DELETE FROM cart
  WHERE cart.id = 1
  RETURNING *
)

SELECT cart.id, product.name, product.descr, product.price, cart.quantity
FROM cart INNER JOIN product
ON cart.product_id = product.id
WHERE cart.user_id = (SELECT user_id FROM removed);

However, it seems that the main SELECT query is returning before delete, so the changes are not reflected. From what I've read in the PostgreSQL documentation:

The sub-statements in WITH are executed concurrently with each other and with the main query.

Is there an alternative method I could use to return the select statement after the update/deletion from the table?

Like you quoted the manual yourself (though pointing to the outdated Postgres 9.1), changes made in CTEs of the same statement are not visible in the underlying tables.

I suggest this workaround:

WITH removed AS (
   DELETE FROM cart
   WHERE id = 1
   RETURNING user_id
   )
SELECT c.id, p.name, p.descr, p.price, c.quantity
FROM   cart c
JOIN   product p ON c.product_id = p.id
WHERE  c.user_id = (SELECT user_id FROM removed);
AND    c.cart.id <> 1;  --  repreat negated filter from above

Else, you need two separate statements (nested in the same transaction). The second (SELECT) would then see effects of the first. You just have to remember the affected user_id somehow...

Just replace cart by removed in the FROM clause of the SELECT :

WITH removed AS (
  DELETE FROM cart
  WHERE cart.id = 1
  RETURNING *
)
SELECT removed.id, product.name, product.descr, product.price, removed.quantity
FROM removed INNER JOIN product
ON removed.product_id = product.id ;

The removed row no more exist in table cart when the SELECT is executed, but they are stored in a temporary table thanks to the RETURNING clause.

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