MySQL新手求助:如何关联三张表生成人员技能持有状态全量结果
搞定MySQL三表关联的人员-技能全组合标记问题
嘿,作为MySQL新手遇到这种关联查询问题很正常,我来帮你捋清楚怎么改!你的需求是要列出所有人员和所有技能的组合,然后标记每个组合是否在关联表中存在,对吧?
先看你原SQL的问题:用了默认的内连接(JOIN就是INNER JOIN),这会自动过滤掉没有关联的记录,而且连接条件没写对,加上没必要的GROUP BY,结果自然不对。
正确的SQL语句
SELECT ROW_NUMBER() OVER(ORDER BY p.person_id, s.skill_id) AS id, p.person_name, s.skill_name, CASE WHEN ps.person_id IS NOT NULL THEN 'YES' ELSE 'NO' END AS excist FROM person_table p CROSS JOIN skill_table s LEFT JOIN person_skill_table ps ON p.person_id = ps.person_id AND s.skill_id = ps.skill_id ORDER BY p.person_id, s.skill_id;
一步步解释为什么这么写
- CROSS JOIN生成全组合:先把
person_table和skill_table做交叉连接,这样就能得到每个人员对应所有技能的全部组合——这正是你预期结果里前四行的基础。 - LEFT JOIN关联关系表:把上面的全组合和
person_skill_table做左连接,这样就算某个人员没有对应的技能,这个组合也会保留下来,只是关联表的字段会是NULL。 - CASE判断标记存在性:只要关联表的
person_id(或者skill_id)不是NULL,就说明这个人员-技能组合存在,标记为YES,否则就是NO。 - ROW_NUMBER()生成自增ID:按照人员ID和技能ID的顺序生成自增的
id字段,和你预期的结果格式完全匹配。
原SQL的问题出在哪?
- 内连接会过滤掉无关联记录:比如user2没有任何技能关联,用内连接的话,user2的技能组合会被错误过滤;
- 连接条件逻辑混乱:你没指定正确的关联匹配规则,导致关联表的匹配结果出错;
- 多余的
GROUP BY:分组会破坏原本的人员-技能组合关系,完全没必要添加。
执行上面的正确语句后,就能得到你想要的完美结果啦!
内容的提问来源于stack exchange,提问作者Nairb
相关产品推荐
相关产品推荐

