繁体   English   中英

PostgreSQL WITH查询,执行顺序

[英]PostgreSQL WITH query, execution order

我正在尝试从表中更新/删除,然后通过内部联接返回更新的数据,如下所示:

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);

但是,似乎主要的SELECT查询在删除之前返回,因此没有反映更改。 从我在PostgreSQL文档中读到的内容:

WITH中的子语句彼此同时执行,并与主查询同时执行。

在从表中更新/删除之后,我可以使用另一种方法来返回 select 语句吗?

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

我建议这种解决方法:

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

否则,您需要两个单独的语句(嵌套在同一个事务中)。 然后第二个(SELECT)将看到第一个的效果。 您只需要以某种方式记住受影响的user_id ...

只需在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 ;

执行SELECT时,删除的行不再存在于表cart中,但由于RETURNING子句,它们存储在临时表中。

暂无
暂无

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

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