[英]Postgres | Execute delete cte after insert cte
I have a table:我有一张桌子:
CREATE TABLE product
(
id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
from_id bigint NOT NULL,
to_id bigint NOT NULL,
comments text NOT NULL,
data jsonb NOT NULL
);
CREATE UNIQUE INDEX product_unique_idx ON product(from_id, to_id, comments);
With the following data:使用以下数据:
insert into product(from_id, to_id, comments, data) values
(1, 2, 'bla', '{}'),
(2, 3, 'bla', '{}'),
(1, 3, 'bla', '{}'),
(3, 2, 'bla', '{}'),
(2, 1, 'bla', '{}'),
(3, 1, 'bla', '{}');
Now, I want to insert new records that will update from_id & to_id with a given collection, for example replace all from_id & to_ids [1,2] with 3 (also delete where from_id == to_id), because of the UNIQUE INDEX
I do it via insert
and then delete
all other rows:现在,我想插入将使用给定集合更新 from_id 和 to_id 的新记录,例如,将所有 from_id 和 to_ids [1,2] 替换为 3(也删除 where from_id == to_id),因为我使用了
UNIQUE INDEX
它通过insert
然后delete
所有其他行:
with
insert_stmt_to_id AS (
insert into product
(from_id, to_id, comments, data)
(select from_id,3,comments,data from product
where to_id in (1,2))
ON CONFLICT (from_id, to_id, comments) DO NOTHING),
insert_stmt_from_id AS (
insert into product
(from_id, to_id, comments, data)
(select 3,to_id,comments,data from product
where from_id in (1,2))
ON CONFLICT (from_id, to_id, comments) DO NOTHING),
delete_stmt AS (DELETE from product where to_id in (1,2) or from_id in (1,2) RETURNING *)
select * from delete_stmt
But after select * from product
, I get (there are [1, 2] in from+it\to_id):但是在
select * from product
之后,我得到(在 from+it\to_id 中有 [1, 2]):
How is it?如何?
So I've managed to do so:所以我设法做到了:
with
delete_duplicates as (
delete from product where
(from_id in (1,2) and to_id in (1,2)) or
(from_id = 3 and to_id in (1,2)) or
(from_id in (1,2) and to_id = 3)
RETURNING id),
insert_stmt_from_id AS (
insert into product
(from_id, to_id, comments, data)
(select 3,to_id,comments,data from product
where from_id in (1,2) and not id in (select id from delete_duplicates))
ON CONFLICT (from_id, to_id, comments) DO NOTHING RETURNING id),
insert_stmt_to_id AS (
insert into product
(from_id, to_id, comments, data)
(select from_id,3,comments,data from product
where to_id in (1,2) and not id in (select id from delete_duplicates))
ON CONFLICT (from_id, to_id, comments) DO NOTHING RETURNING id),
delete_leftovers_stmt AS (DELETE from product where from_id in (1,2) or to_id in (1,2) RETURNING id)
select id from delete_duplicates union select id from delete_leftovers_stmt;
You need a transaction , so that all commands are run in an extra state and it will give you an answer with only one as result你需要一个事务,以便所有命令都在一个额外的状态下运行,它会给你一个答案,结果只有一个
BEGIN; insert into product (from_id, to_id, comments, data) (select from_id,3,comments,data from product where to_id in (1,2)) ON CONFLICT (from_id, to_id, comments) DO NOTHING; insert into product (from_id, to_id, comments, data) (select 3,to_id,comments,data from product where from_id in (1,2)) ON CONFLICT (from_id, to_id, comments) DO NOTHING; DELETE from product where to_id in (1,2) or from_id in (1,2); COMMIT;
✓✓ 1 rows affected
1 行受影响 ✓
✓ 6 rows affected
6 行受影响 ✓
✓
SELECT * FROM product
id |编号 | from_id |
from_id | to_id |
to_id | comments |
评论 | data
数据 -: |
-: | ------: |
------: | ----: |
----: | :------- |
:------- | :---
:--- 8 |
8 | 3 |
3 | 3 |
3 | bla |
布拉| {}
{}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.