MySQL根据sink_node_type字段值关联不同表的查询问题求助
解决MySQL根据类型关联不同表的问题
你分析得完全正确——问题出在内连接(INNER JOIN)的互斥条件上:一条node记录的sink_type只能是其中一个值(比如'a'或'b',不可能同时满足两个JOIN的条件),所以同时用两个INNER JOIN会导致没有匹配的记录,结果集为空。
针对你的场景(有6个sink_type表),这里有几种可行的解决方案:
方案1:使用左外连接(LEFT JOIN)保留所有记录
这是最直接的方式,用LEFT JOIN替代INNER JOIN,这样即使某个sink_type表没有匹配的记录,也会保留node和project的信息,不匹配的字段会显示为NULL:
select p.name as project_name, sa.name as sink_a_name, sb.name as sink_b_name, sc.name as sink_c_name, sd.name as sink_d_name, se.name as sink_e_name, sf.name as sink_f_name from project p join node n on p.id = n.project_id left join sink_type_a sa on n.sink_id = sa.id and n.sink_type = 'a' left join sink_type_b sb on n.sink_id = sb.id and n.sink_type = 'b' left join sink_type_c sc on n.sink_id = sc.id and n.sink_type = 'c' left join sink_type_d sd on n.sink_id = sd.id and n.sink_type = 'd' left join sink_type_e se on n.sink_id = se.id and n.sink_type = 'e' left join sink_type_f sf on n.sink_id = sf.id and n.sink_type = 'f';
效果说明
每条node记录只会在对应的sink_type字段上有值,其他sink名称字段为NULL。比如sink_type='a'的记录,sink_a_name会显示对应的值,sink_b_name到sink_f_name都是NULL。
方案2:用CASE表达式合并为单个sink名称字段
如果不需要同时显示所有sink类型的字段,只想得到当前node对应的sink名称,可以用CASE表达式来匹配对应的表:
select p.name as project_name, n.sink_type, case n.sink_type when 'a' then sa.name when 'b' then sb.name when 'c' then sc.name when 'd' then sd.name when 'e' then se.name when 'f' then sf.name end as sink_name from project p join node n on p.id = n.project_id left join sink_type_a sa on n.sink_id = sa.id left join sink_type_b sb on n.sink_id = sb.id left join sink_type_c sc on n.sink_id = sc.id left join sink_type_d sd on n.sink_id = sd.id left join sink_type_e se on n.sink_id = se.id left join sink_type_f sf on n.sink_id = sf.id;
效果说明
结果集中会有一个统一的sink_name字段,直接显示当前node对应的sink表的名称,不需要区分多个字段。
方案3:合并所有sink表后关联(适合表结构一致的场景)
如果6个sink_type表的结构完全一致(比如都有id和name字段),可以先用UNION ALL把它们合并成一个虚拟表,再和node、project关联,这样逻辑更简洁:
select p.name as project_name, combined_sink.name as sink_name, combined_sink.sink_type from project p join node n on p.id = n.project_id join ( select id, name, 'a' as sink_type from sink_type_a union all select id, name, 'b' as sink_type from sink_type_b union all select id, name, 'c' as sink_type from sink_type_c union all select id, name, 'd' as sink_type from sink_type_d union all select id, name, 'e' as sink_type from sink_type_e union all select id, name, 'f' as sink_type from sink_type_f ) combined_sink on n.sink_id = combined_sink.id and n.sink_type = combined_sink.sink_type;
效果说明
这种方式用内连接就能得到准确匹配的结果,因为合并后的虚拟表已经包含了所有sink类型的记录,node只会匹配到对应类型的那条记录。
内容的提问来源于stack exchange,提问作者anja123
相关产品推荐
相关产品推荐

