基于UserInfo、Skill、UserSkill表查询掌握Java用户的其他技能需求
嘿,这个需求其实就是典型的「基于共同技能的相关技能推荐」,我来给你一步步拆解实现方法!
核心思路
逻辑其实很简单,分三步走:
- 先找出所有掌握Java技能的用户
- 再收集这些用户的全部技能清单
- 最后把Java本身排除掉,再去重,剩下的就是你要的相关技能啦
实现SQL代码
先假设你的表结构是常规设计:
UserInfo:存用户基础信息,主键是userIdSkill:存技能信息,有skillId(主键)和skillName(技能名称,比如"Java")UserSkill:用户-技能关联表,用userId和skillId做联合主键
对应的查询SQL如下:
SELECT DISTINCT s.skillName FROM UserSkill us JOIN Skill s ON us.skillId = s.skillId WHERE us.userId IN ( -- 子查询:先拿到所有会Java的用户ID SELECT us_inner.userId FROM UserSkill us_inner JOIN Skill s_inner ON us_inner.skillId = s_inner.skillId WHERE s_inner.skillName = 'Java' ) AND s.skillName != 'Java'; -- 把Java本身排除出去
代码说明
- 内层的子查询负责筛选出所有掌握Java的用户ID集合,这一步是整个查询的基础
- 外层查询通过关联
UserSkill和Skill,把这些用户的所有技能都拉出来,用DISTINCT保证同一个技能只显示一次(比如多个用户都会Python,不会重复输出) - 用
s.skillName != 'Java'把Java本身排除,剩下的就是和Java相关的其他技能啦 - 按照你举的例子,这个查询会返回
Go、PHP、Python、CSS,完全符合你的预期
进阶玩法(贴近推荐系统)
如果想让结果更像推荐系统,比如按技能的流行程度排序(看多少Java用户也掌握这个技能),可以给每个技能加个用户数统计:
SELECT s.skillName, COUNT(DISTINCT us.userId) AS user_count FROM UserSkill us JOIN Skill s ON us.skillId = s.skillId WHERE us.userId IN ( SELECT us_inner.userId FROM UserSkill us_inner JOIN Skill s_inner ON us_inner.skillId = s_inner.skillId WHERE s_inner.skillName = 'Java' ) AND s.skillName != 'Java' GROUP BY s.skillName ORDER BY user_count DESC;
这样结果会按技能的热门程度从高到低排列,推荐逻辑更合理~
内容的提问来源于stack exchange,提问作者Pantea
相关产品推荐
相关产品推荐

