PostgreSQL关联表行转列 实现父子关系类Excel格式查询
PostgreSQL 固定列父子关联行转列实现方案
你这个固定输出3列Guest的场景不需要依赖crosstab()函数,用窗口函数+条件聚合的方式实现逻辑更清晰,结果稳定,完全适配视图创建要求,不会出现crosstab常见的类别匹配错位问题。
核心实现思路
- 先给每个Person下关联的Guest按规则排序编号,编号从1开始,和目标列的Guest序号一一对应
- 以Person表为主表左关联带编号的Guest数据,通过条件聚合把对应编号的Guest名称映射到指定列,无匹配值时统一填充
--
可直接部署的视图SQL
CREATE OR REPLACE VIEW v_person_guest_excel_format AS SELECT p.name AS "Person Name", COALESCE(MAX(CASE WHEN g.guest_seq = 1 THEN g.name END), '--') AS "Guest 1 Name", COALESCE(MAX(CASE WHEN g.guest_seq = 2 THEN g.name END), '--') AS "Guest 2 Name", COALESCE(MAX(CASE WHEN g.guest_seq = 3 THEN g.name END), '--') AS "Guest 3 Name" FROM person p LEFT JOIN ( SELECT id_person, name, ROW_NUMBER() OVER (PARTITION BY id_person ORDER BY id) AS guest_seq FROM guest ) g ON p.id = g.id_person GROUP BY p.id, p.name ORDER BY p.id;
输出效果
查询视图SELECT * FROM v_person_guest_excel_format即可得到符合要求的类Excel格式结果:
| Person Name | Guest 1 Name | Guest 2 Name | Guest 3 Name |
|---|---|---|---|
| A | AGuest1 | -- | -- |
| B | BGuest1 | BGuest2 | -- |
| C | CGuest1 | CGuest2 | CGuest3 |
扩展说明
- 如果后续需要调整Guest列数量,只需要增减SELECT子句中对应序号的条件聚合语句即可,维护成本远低于crosstab方案
- 子查询中
ROW_NUMBER()的ORDER BY id可以根据业务需求替换为其他排序规则,比如按Guest创建时间、姓名字母序排序 - 空值填充逻辑通过
COALESCE实现,不需要额外做二次结果处理
内容的提问来源于stack exchange,提问作者varijkapil13
相关产品推荐
相关产品推荐

