PostgreSQL 12中如何依据rowspan将行式数据转换为目标表结构
PostgreSQL 实现跨行数据的列转换与行对齐
解决方案核心逻辑
通过generate_series根据rowspan字段生成对应数量的重复行,再结合条件聚合将不同列的数据映射到目标三列,实现严格的行对齐。
完整SQL代码
WITH expanded_rows AS ( -- 按rowspan扩展每行数据,生成对应数量的重复行 SELECT frame_rows, generate_series(1, rowspan) AS row_num, frame_column, single_value FROM test ) -- 按扩展后的行组聚合,将不同frame_column的值映射到目标列 SELECT MAX(CASE WHEN frame_column = 1 THEN single_value END) AS Output, MAX(CASE WHEN frame_column = 2 THEN single_value END) AS Sub_output, MAX(CASE WHEN frame_column = 3 THEN single_value END) AS target FROM expanded_rows GROUP BY frame_rows, row_num ORDER BY frame_rows, row_num;
逻辑说明
- 扩展行:使用
generate_series(1, rowspan)为每条记录生成rowspan个重复行,确保跨行的单元格能占据指定行数。例如rowspan=2的记录会被拆成2行,共享同一个frame_rows和递增的row_num。 - 条件聚合:按
frame_rows(原数据的行组)和row_num(扩展后的行序号)分组,用CASE WHEN将不同frame_column对应的single_value填充到Output/Sub_output/target列,同一组内的非对应列会取MAX(因同一组内对应列只有一个值,其他为NULL,MAX会保留有效数据)。
示例验证
假设test表原始数据:
| cell | single_value | frame_column | frame_rows | rowspan |
|---|---|---|---|---|
| A1 | 系统输出1 | 1 | 1 | 2 |
| A2 | 子项1 | 2 | 1 | 1 |
| A3 | 目标值1 | 3 | 1 | 1 |
| B1 | 系统输出2 | 1 | 2 | 1 |
| B2 | 子项2 | 2 | 2 | 1 |
| B3 | 目标值2 | 3 | 2 | 1 |
执行SQL后输出:
| Output | Sub_output | target |
|---|---|---|
| 系统输出1 | 子项1 | 目标值1 |
| 系统输出1 | NULL | NULL |
| 系统输出2 | 子项2 | 目标值2 |
完全符合rowspan的跨行要求,行对齐无误。
注意事项
- 需确保
frame_column的取值与目标列一一对应(示例中1=Output、2=Sub_output、3=target),可根据实际业务调整CASE WHEN的判断条件。 - 若需将NULL替换为空字符串,可使用
COALESCE(MAX(...), '')。 - 若
frame_rows并非行组的唯一标识,需补充其他分组字段保证数据准确性。
内容的提问来源于stack exchange,提问作者David Figueroa
相关产品推荐
相关产品推荐

