[英]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
:只需在SELECT
的FROM
子句中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.