You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Postgres如何将分组多行合并为单行插入目标表

解决方案

你遇到的报错本质是同个Id对应多行原始数据,插入时会先后触发同一Id的多次冲突更新,PostgreSQL不允许同事务内多次修改同一行。只要先把原始长表按Id聚合成宽表结构,再执行插入操作即可解决问题。

1. 核心逻辑:长表转宽表

使用PostgreSQL的FILTER聚合语法可以非常简洁的完成行列转换,每个Id仅返回一行结果:

SELECT
  Id,
  MAX(value) FILTER (WHERE category = 'a') AS category_a_value,
  MAX(value) FILTER (WHERE category = 'b') AS category_b_value
FROM 替换为你的原始数据查询语句
GROUP BY Id

如果使用的是10以下不支持FILTER的旧版本PostgreSQL,可以用CASE WHEN替代:

SELECT
  Id,
  MAX(CASE WHEN category = 'a' THEN value END) AS category_a_value,
  MAX(CASE WHEN category = 'b' THEN value END) AS category_b_value
FROM 替换为你的原始数据查询语句
GROUP BY Id

2. 插入目标表(支持冲突更新)

把上面的聚合查询结果直接作为插入的数据源即可,因为每个Id只有一行数据,不会再触发同个行多次修改的报错:

INSERT INTO 你的目标表名 (Id, category_a_value, category_b_value)
SELECT
  Id,
  MAX(value) FILTER (WHERE category = 'a') AS category_a_value,
  MAX(value) FILTER (WHERE category = 'b') AS category_b_value
FROM 替换为你的原始数据查询语句
GROUP BY Id
-- 如果需要处理Id重复的冲突场景,保留下面的ON CONFLICT逻辑,不需要可以删掉
ON CONFLICT (Id) DO UPDATE SET
  category_a_value = EXCLUDED.category_a_value,
  category_b_value = EXCLUDED.category_b_value;

如果后续新增了其他category类型,只需要在SELECT部分新增对应的FILTER聚合列即可,整体逻辑不需要调整。

内容的提问来源于stack exchange,提问作者anon_6891

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 02:36:03