mysqli多表关联查询求助:工单与帮助主题表层级数据展示问题
解决多级主题关联查询的优化方案
嘿,我来帮你搞定这个关联查询的问题!你之前用单关联拿不全数据、多次查询又处理不好缺失层级的情况,其实用一次自关联的MySQL查询就能完美解决需求。
优化后的查询语句
SELECT t.ticket_id, COALESCE(cat.topic_name, '') AS category, COALESCE(ct.topic_name, '') AS case_type, COALESCE(subct.topic_name, '') AS sub_case_type FROM ticket t -- 关联到ticket对应的主题记录(不管是哪个层级) LEFT JOIN help_topic current_t ON t.topic_id = current_t.topic_id -- 匹配子案例类型(仅当当前主题是sort=2时生效) LEFT JOIN help_topic subct ON current_t.topic_id = subct.topic_id AND subct.sort = 2 -- 匹配案例类型:要么当前主题是sort=1,要么是sort=2的父级(sort=1) LEFT JOIN help_topic ct ON (current_t.sort = 2 AND current_t.parent_id = ct.topic_id) OR (current_t.sort = 1 AND current_t.topic_id = ct.topic_id) AND ct.sort = 1 -- 匹配分类:要么是案例类型的父级(sort=0),要么当前主题本身就是sort=0 LEFT JOIN help_topic cat ON (ct.topic_id IS NOT NULL AND ct.parent_id = cat.topic_id) OR (current_t.sort = 0 AND current_t.topic_id = cat.topic_id) AND cat.sort = 0;
逻辑拆解
- 基础关联:先通过
current_t拿到每张ticket对应的主题记录,不管它属于分类(sort=0)、案例类型(sort=1)还是子案例类型(sort=2)。 - 子案例类型匹配:只有当当前主题是最底层的sort=2时,
subct才会有值,否则返回空字符串(通过COALESCE把NULL转成空)。 - 案例类型匹配:分两种场景处理:
- 如果当前主题是子案例类型(sort=2),就关联它的父级(sort=1)作为案例类型;
- 如果当前主题本身就是案例类型(sort=1),直接用它自己。
- 分类匹配:同样分两种场景:
- 如果已经匹配到案例类型,就关联它的父级(sort=0)作为分类;
- 如果当前主题本身就是分类(sort=0),直接用它自己。
- 空值处理:用
COALESCE函数把所有NULL结果转换成空字符串,完全符合你“无对应层级则留空”的要求。
这个方案用一次查询覆盖了所有可能的层级组合,不管ticket对应的主题是哪个层级,都能正确输出对应的字段,再也不用多次查询拼接结果啦!
内容的提问来源于stack exchange,提问作者may
相关产品推荐
相关产品推荐

