Home > Blockchain >  PostgreSQL WITH query, execution order
PostgreSQL WITH query, execution order

Time:12-18

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?

CodePudding user response:

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;  --  repeat negated filter from above

<> is the "not equal" operator and the opposite of =. cart.id <> 1 excludes the row(s) to be deleted with WHERE id = 1.

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 ...

  • Related