PostgreSQL中同时关联两表至visit表返回空结果的问题排查
问题原因及解决方案
核心原因
你当前用的是内连接(INNER JOIN),PostgreSQL里写JOIN默认就是内连接。内连接的规则是:只有当关联条件在所有参与连接的表中都匹配到数据时,才会返回该行。
从你描述的情况来看:
- 单独连
penn_survey有结果:说明部分visit_id在visit和penn_survey中同时存在 - 单独连
brazil_legacy_survey有结果:说明部分visit_id在visit和brazil_legacy_survey中同时存在 - 同时连两个表返回空:没有任何一个
visit_id同时存在于visit、penn_survey和brazil_legacy_survey三个表中,也就是两个survey表的visit_id集合完全没有交集。
解决方案
如果你的需求是保留visit表的所有数据,同时关联两个survey表(不管对应survey有没有数据),把内连接改成**左连接(LEFT JOIN)**即可:
-- 左连接保留visit表数据,无对应survey数据时显示NULL select v.date, v.site, ps.site as penn_site, ps.date as penn_date, b.site as brazil_site, b.date as brazil_date from visit v left join penn_survey ps on ps.visit_id = v.visit_id left join brazil_legacy_survey b on b.visit_id = v.visit_id
关于你的其他疑问
列名是否需要修改?
不需要。你已经通过表别名(ps、b)区分了重复列(比如ps.site和b.site),查询时不会有歧义。如果觉得结果列名混乱,可以像上面的示例一样给列起别名(as penn_site)。是否需要单独的外键ID?
如果业务逻辑是一个visit只会对应其中一个survey表(不会同时属于两个survey),那当前用同一个visit_id关联是合理的,不需要单独的外键ID。如果业务上允许一个visit对应多个survey,那你需要检查数据是否真的存在这样的记录——从当前查询结果来看是没有的。
验证数据分布的查询
可以用下面的SQL确认两个survey表的visit_id是否有交集:
-- 查看同时存在于两个survey表的visit_id select ps.visit_id from penn_survey ps join brazil_legacy_survey b on ps.visit_id = b.visit_id; -- 查看各表的visit_id数量 select 'penn_survey' as table_name, count(distinct visit_id) as id_count from penn_survey union all select 'brazil_legacy_survey' as table_name, count(distinct visit_id) as id_count from brazil_legacy_survey union all select 'visit' as table_name, count(distinct visit_id) as id_count from visit;
内容的提问来源于stack exchange,提问作者Eizy
相关产品推荐
相关产品推荐

