簡體   English   中英

Postgres | 插入 cte 后執行 delete cte

[英]Postgres | Execute delete cte after insert cte

我有一張桌子:

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

使用以下數據:

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', '{}');

現在,我想插入將使用給定集合更新 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 

但是在select * from product之后,我得到(在 from+it\to_id 中有 [1, 2]):

在此處輸入圖像描述

如何?

所以我設法做到了:

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;

你需要一個事務,以便所有命令都在一個額外的狀態下運行,它會給你一個答案,結果只有一個

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 行受影響

 

 6 行受影響

 
SELECT * FROM product
編號 |  from_id |  to_id | 評論 | 數據
 -: |  ------: |  ----: |  :------- |  :---
  8 |  3 |  3 | 布拉|  {}  

db<> 在這里擺弄

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM