简体   繁体   English

PostgreSQL WITH查询,执行顺序

[英]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.但是,似乎主要的SELECT查询在删除之前返回,因此没有反映更改。 From what I've read in the PostgreSQL documentation:从我在PostgreSQL文档中读到的内容:

The sub-statements in WITH are executed concurrently with each other and with the main query. WITH中的子语句彼此同时执行,并与主查询同时执行。

Is there an alternative method I could use to return the select statement after the update/deletion from the table?在从表中更新/删除之后,我可以使用另一种方法来返回 select 语句吗?

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.就像您自己引用手册一样(尽管指向过时的 Postgres 9.1),在同一语句的 CTE 中所做的更改在基础表中不可见。

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.然后第二个(SELECT)将看到第一个的效果。 You just have to remember the affected user_id somehow...您只需要以某种方式记住受影响的user_id ...

Just replace cart by removed in the FROM clause of the SELECT :只需在SELECTFROM子句中removed即可替换cart

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.执行SELECT时,删除的行不再存在于表cart中,但由于RETURNING子句,它们存储在临时表中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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