客户拥有以下表格之一:

row_index id seq value_text
1007_0_0 1007 1 800
1007_0_0 1007 2 1110
1007_0_0 1007 4 road, roadwork
1007_0_0 1007 5 100
1007_0_1 1007 1 800
1007_0_1 1007 2 1115
1007_0_1 1007 4 road, roadwork
1007_0_1 1007 5 100
1007_0_2 1007 1 800
1007_0_2 1007 2 1105
1007_0_2 1007 4 road, roadwork
1007_0_2 1007 5 100
1007_0_3 1007 1 800
1007_0_3 1007 2 1120
1007_0_3 1007 4 road, roadwork
1007_0_3 1007 5 100
1007_0 1007 6 Rosedale
1007_0 1007 8 139

我试图实现的是将二元组行添加到每个子组(row_index)组中以进行透视.

最终结果应该是这样的:

row_index id seq value_text
1007_0_0 1007 6 Rosedale
1007_0_0 1007 8 139
1007_0_0 1007 1 800
1007_0_0 1007 2 1110
1007_0_0 1007 4 road, roadwork
1007_0_0 1007 5 100
1007_0_1 1007 6 Rosedale
1007_0_1 1007 8 139
1007_0_1 1007 1 800
1007_0_1 1007 2 1115
1007_0_1 1007 4 road, roadwork
1007_0_1 1007 5 100
1007_0_2 1007 6 Rosedale
1007_0_2 1007 8 139
1007_0_2 1007 1 800
1007_0_2 1007 2 1105
1007_0_2 1007 4 road, roadwork
1007_0_2 1007 5 100
1007_0_3 1007 6 Rosedale
1007_0_3 1007 8 139
1007_0_3 1007 1 800
1007_0_3 1007 2 1120
1007_0_3 1007 4 road, roadwork
1007_0_3 1007 5 100

推荐答案

如果强调线的数量告诉您什么是二元组,什么是子二元组,则您可以通过以regexp_count()为目标来将这些二元组delete..returning,将它们连接到匹配的子二元组,然后在添加不同的子二元组后缀(用split_part()提取)后重新插入它们.

Demo at db<>fiddle:

with tuple as (delete from your_table where regexp_count(row_index,'_')=1
                returning *)
insert into your_table
select distinct 
       tuple.row_index||'_'||split_part(subtuple.row_index,'_',3)
      ,tuple.id
      ,tuple.seq
      ,tuple.value_text 
from tuple join your_table subtuple 
  on  regexp_count(subtuple.row_index,'_')=2
  --and subtuple.row_index ~ ('^'||tuple.row_index)
  and tuple.id=subtuple.id
--returning *--this would suffice to show what got inserted
;
--full view to make the end result clearly match expectation
select * from your_table order by row_index,seq<6,seq;
row_index id seq value_text
1007_0_0 1007 6 Rosedale
1007_0_0 1007 8 139
1007_0_0 1007 1 800
1007_0_0 1007 2 1110
1007_0_0 1007 4 road, roadwork
1007_0_0 1007 5 100
1007_0_1 1007 6 Rosedale
1007_0_1 1007 8 139
1007_0_1 1007 1 800
1007_0_1 1007 2 1115
1007_0_1 1007 4 road, roadwork
1007_0_1 1007 5 100
1007_0_2 1007 6 Rosedale
1007_0_2 1007 8 139
1007_0_2 1007 1 800
1007_0_2 1007 2 1105
1007_0_2 1007 4 road, roadwork
1007_0_2 1007 5 100
1007_0_3 1007 6 Rosedale
1007_0_3 1007 8 139
1007_0_3 1007 1 800
1007_0_3 1007 2 1120
1007_0_3 1007 4 road, roadwork
1007_0_3 1007 5 100

如果您通过将row_index字段替换为同一个表中的一个整标识符字段,并将另一个字段替换为指向父组的外部关键字来规范化您的 struct ,那会更容易.这样,您就可以按照您想要的深度嵌套二元组,而不必解析/拆分/重新组装row_index中的文本值,由于数字类型,可以更快地查找和连接,并使用pgroutingApache AGE或仅recursive CTE来穿越整个 struct .

row_index可以保留以实现向后兼容性,而您的性能敏感操作基于数字标识符.您甚至可以让触发器处理根据外部密钥生成和维护row_index.

Sql相关问答推荐

Postgresql在加入时显示重复的行

如何以"% m—% d"格式对生日列表进行排序,以查找与今天最近的日期?

有没有一种正确的方法来利用SQL UNION来从三个潜在查询中 Select 最大值?

在SQL中使用类别值将行转置为列

如何在PostgreSQL中对第1,1,1,1,2,2,2,2行进行编号

统计PostgreSQL中前10个最大大小表的行数

SQL中相同表内的VLOOKUP等价

更改重复值的情况

Postgresql - WHERE 中的 MAX 标准 - 初学者问题

DbUp for sqlserver 在 dbo 授权下为非 dbo 用户创建架构

在 PostgreSQL 中,如何让多个判断约束引用相同的值数组?

如何在 JSONB 数组的每个对象中添加新的键值对- PostgreSQL

如何在插入时将字符串'03-January-2023'转换为日期时间

Clob 问题 - 将 clob 列拆分为多行

条件意外地显着降低性能的地方

为什么 Oracle 在一个查询中对同一张表同时执行 TABLE SCAN 和 INDEX UNIQUE SCAN?

连接表时避免重复

将单行中的多个行值转换为列

如何使用子查询锁定此查询中的选定行?

Postgres 窗口函数未按预期工作