PostgreSQL 13:如何将N张表的数据合并为最终结果?
解决方案
一、2张表的合并实现
使用FULL OUTER JOIN关联共同列sf_id,即可保留两表中所有sf_id,不存在的列自动填充NULL。
对应SQL语句:
SELECT COALESCE(t1.sf_id, t2.sf_id) AS sf_id, t1.acc_count, t1.ver, t2.cont_count, t2.dis_count FROM test1 t1 FULL OUTER JOIN test2 t2 ON t1.sf_id = t2.sf_id ORDER BY sf_id;
关键说明
COALESCE(t1.sf_id, t2.sf_id):确保sf_id列始终取非空值,不管该ID来自哪张表FULL OUTER JOIN:返回两个表中所有匹配和不匹配的行,不匹配的行对应另一表的列自动填充NULL
执行结果完全符合预期:
| sf_id | acc_count | ver | cont_count | dis_count |
|---|---|---|---|---|
| S1 | 5 | 1.0.0 | 100 | 50 |
| S2 | 10 | 9.8 | NULL | NULL |
| S3 | NULL | NULL | 500 | 78 |
二、N张表的通用合并方案
针对3张及以上表的场景,有两种可靠思路:
思路1:链式全外连接
依次对每张表执行FULL OUTER JOIN,以3张表为例:
SELECT COALESCE(t1.sf_id, t2.sf_id, t3.sf_id) AS sf_id, t1.acc_count, t1.ver, t2.cont_count, t2.dis_count, t3.col1, t3.col2 FROM test1 t1 FULL OUTER JOIN test2 t2 ON t1.sf_id = t2.sf_id FULL OUTER JOIN test3 t3 ON COALESCE(t1.sf_id, t2.sf_id) = t3.sf_id ORDER BY sf_id;
思路2:先收集所有唯一sf_id,再左连接所有表
这种方式逻辑更清晰,适合表数量较多的场景:
- 通过
UNION收集所有表中唯一的sf_id - 以此为基础,分别左连接每张表获取对应列
以3张表为例:
WITH all_sf_ids AS ( SELECT sf_id FROM test1 UNION SELECT sf_id FROM test2 UNION SELECT sf_id FROM test3 ) SELECT a.sf_id, t1.acc_count, t1.ver, t2.cont_count, t2.dis_count, t3.col1, t3.col2 FROM all_sf_ids a LEFT JOIN test1 t1 ON a.sf_id = t1.sf_id LEFT JOIN test2 t2 ON a.sf_id = t2.sf_id LEFT JOIN test3 t3 ON a.sf_id = t3.sf_id ORDER BY sf_id;
关键说明
UNION自动去重,确保all_sf_ids包含所有唯一的sf_id- 每个
LEFT JOIN将当前表数据匹配到对应sf_id,不匹配的列填充NULL
为什么之前的方法失效?
- 普通内连接(
JOIN)仅返回两表共有的sf_id,丢失仅在单表存在的ID UNION要求所有查询的列数、类型完全一致,而你的表结构不同,无法直接使用
内容的提问来源于stack exchange,提问作者Vikas J
相关产品推荐
相关产品推荐

