PostgreSQL WITH查询,执行顺序
PostgreSQL WITH query, execution order
我正在尝试从 table update/delete,然后 return 通过这样的内部联接更新数据:
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
查询似乎是 returning 在删除之前,所以更改没有反映出来。根据我在 PostgreSQL 文档中阅读的内容:
The sub-statements in WITH
are executed concurrently with each other and with the main query.
我可以使用替代方法 return table 中 update/deletion 之后的 select 语句吗?
就像您自己引用 the manual 一样(尽管指向过时的 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; -- repeat negated filter from above
<>
is the "not equal" operator与=
相反。 cart.id <> 1
排除要删除的行 WHERE id = 1
。
否则,您需要两个单独的语句(嵌套在同一事务中)。第二个 (SELECT) 将看到第一个的效果。您只需要以某种方式记住受影响的 user_id
...
我正在尝试从 table update/delete,然后 return 通过这样的内部联接更新数据:
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
查询似乎是 returning 在删除之前,所以更改没有反映出来。根据我在 PostgreSQL 文档中阅读的内容:
The sub-statements in
WITH
are executed concurrently with each other and with the main query.
我可以使用替代方法 return table 中 update/deletion 之后的 select 语句吗?
就像您自己引用 the manual 一样(尽管指向过时的 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; -- repeat negated filter from above
<>
is the "not equal" operator与=
相反。 cart.id <> 1
排除要删除的行 WHERE id = 1
。
否则,您需要两个单独的语句(嵌套在同一事务中)。第二个 (SELECT) 将看到第一个的效果。您只需要以某种方式记住受影响的 user_id
...