假設我有我的Postgres數據庫的兩個表:Postgres的:UPSERT行和更新的主鍵列
create table transactions
(
id bigint primary key,
doc_id bigint not null,
-- lots of other columns...
amount numeric not null
);
-- same columns
create temporary table updated_transactions
(
id bigint primary key,
doc_id bigint not null,
-- lots of other columns...
amount numeric not null
);
兩個表都有隻是一個主鍵,沒有唯一索引。
我需要使用以下規則UPSERT從updated_transactions
行到transactions
:在transactions
和
- ID列值
updated_transactions
不匹配像doc_id
等(除amount
的) - 其他列應匹配
- 當找到匹配行時,更新
amount
和id
列 - 當matc沒有找到行,插入它
id
updated_transactions
中的值取自一個序列。 業務對象只填充updated_transactions
,然後使用upsert查詢將 新行或更新的行合併到transactions
中。 所以我舊的不變的交易保持其id
完好,並且更新的 被分配新的id
s。
在MSSQL和Oracle,這將是一個merge
說法與此類似:
merge into transactions t
using updated_transactions ut on t.doc_id = ut.doc_id, ...
when matched then
update set t.id = ut.id, t.amount = ut.amount
when not matched then
insert (t.id, t.doc_id, ..., t.amount)
values (ut.id, ut.doc_id, ..., ut.amount);
在PostgreSQL,我想應該是這樣的:
insert into transactions(id, doc_id, ..., amount)
select coalesce(t.id, ut.id), ut.doc_id, ... ut.amount
from updated_transactions ut
left join transactions t on t.doc_id = ut.doc_id, ....
on conflict
on constraint transactions_pkey
do update
set amount = excluded.amount, id = excluded.id
的問題是與do update
子句:excluded.id
是transactions
表中的舊值 ,而我需要updated_transactions
的新值。
ut.id
do update
條款無法訪問該值,並且我可以使用的唯一一條 行是excluded
行。但excluded
行只有coalesce(t.id, ut.id)
表達式,它返回現有行的舊id
值。
是否可以使用upsert查詢更新id
和amount
列?
'等欄目像DOC_ID等(除量)應該match'聽起來像一個候選鍵給我。 – wildplasser
doc_id和其他列的值(數量除外)不唯一。我簡化了我的問題中的設置,使我的示例查詢更容易理解。在我的真實情況下,我必須添加一個'row_number()(通過doc_id分區,...按ID排序)'來匹配行。 – yallie
在這種情況下,您不能執行更新而不回退到'id'。 – wildplasser