同时插入和更新记录

问题描述 投票:0回答:1
create table test (
    id serial, 
    contract varchar, 
    amount int, 
    aggregated int, 
    is_aggregate int
);
insert into test (contract, amount, aggregated) 
values ('abc', 100, 0), 
       ('abc', 200, 0), 
       ('xyz',  50, 0), 
       ('xyz',  60, 0);
id 合同 金额 汇总 是_聚合
1 abc 100 0
2 abc 200 0
3 xyz 50 0
4 xyz 60 0

我正在尝试编写一个 SQL 语句,在每个合约的基础上插入聚合行,因此结果应该是这样的:

id 合同 金额 汇总 是_聚合
1 abc 100 1
2 abc 200 1
3 xyz 50 1
4 xyz 60 1
5 abc 300 1
6 xyz 110 1

由于不断从另一个数据源添加新行,因此需要一次性插入聚合行并将聚合行中的“聚合”设置为 1,以避免并发问题。

我尝试了几种方法,但我只走到了这一步:

INSERT INTO test (contract, amount, aggregated, is_aggregate)
SELECT contract,
       SUM(amount) AS sum_amount,
       1,
       1
FROM test
WHERE aggregated IS NULL 
   OR aggregated = 0
GROUP BY contract
HAVING COUNT(*) > 1;

这会插入聚合行,但我不知道如何包含一个子句来将已聚合的行的“聚合”更新为 1。

有人可以帮我吗?预先感谢。

sql postgresql group-by sql-update sql-insert
1个回答
0
投票

您可以将其变成“UPSERT” - 即,如果该行不存在,它会执行 INSERT,如果该行已经存在,它会执行 UPDATE:

INSERT INTO test (contract, amount, aggregated, is_aggregate)
SELECT contract,
       SUM(amount) AS sum_amount,
       1,
       1
FROM test
WHERE aggregated IS NULL 
   OR aggregated = 0
GROUP BY contract
HAVING COUNT(*) > 1
ON DUPLICATE KEY UPDATE
    amount = VALUES(amount),
    aggregated = VALUES(aggregated),
    is_aggregate = VALUES(is_aggregate);
© www.soinside.com 2019 - 2024. All rights reserved.