如果我过度混淆了一些事情,我几天都在为此苦苦挣扎......
我有一系列定义的表:
数据库的结构如下所示:
我需要创建一个显示以下数据的结果集:
对于所有工作角色,展示这些工作中的所有技能 角色。但是,也包括各自组内的技能 在每个角色中不包括(用NULL或任何表示 其他方法)。
请参阅此工作代码以创建表和数据。 SQL Fiddle
抱歉,我做了很多插入来创建一个真实的例子。
请注意,PowerPoint
技能未添加到HR Manager
角色,但会添加来自同一组的其他技能。另请注意Recruitment Policy
技能未添加到Software Manager
角色,但我不需要看到这个差距,因为该角色中不存在该组中的其他技能。
我的目标结果与此类似(为简洁起见,不包括超级明星角色):
RoleTitle GroupTitle SkillTitle SkillIsInRole
----------------------- -------------------------- --------------------------------------
Software Manager Microsoft Office Excel 1
Software Manager Microsoft Office Word 1
Software Manager Microsoft Office PowerPoint 1
Software Manager Microsoft SQL Server Query Design 1
Software Manager Microsoft SQL Server Stored Procedures 1
Software Manager Microsoft SQL Server Failover Clustering 1
HR Manager Microsoft Office Excel 1
HR Manager Microsoft Office Word 1
HR Manager Microsoft Office PowerPoint NULL <-- not added to role but exists in same group as other used skills
HR Manager HR Recruitment Policy 1
答案 0 :(得分:3)
获取与角色相关的组的所有技能有点简单,并在下面相对自我解释的roles
cte中处理。从这个角度来看,我能想到获得技能是否与角色“直接”相关的唯一方法是OUTER APPLY
ING将结果集设置为角色的实际技能结果集。
;WITH skills AS
(
SELECT g.GroupId, g.GroupTitle, s.SkillId, s.SkillTitle
FROM @tbl_GroupsSkills gs
INNER JOIN @tbl_Groups g ON g.GroupId = gs.GroupId
INNER JOIN @tbl_Skills s ON s.SkillId = gs.SkillId
)
, roles AS
(
SELECT DISTINCT jr.Id RoleId, jr.RoleTitle, gs.GroupId
FROM @tbl_jobroles jr
INNER JOIN @tbl_rolesskills rs ON rs.RoleId = jr.ID
INNER JOIN @tbl_GroupsSkills gs ON gs.LinkId = rs.LinkId
)
SELECT
roles.RoleTitle,
skills.GroupTitle,
skills.SkillTitle,
t.SkillIsInRole
FROM skills
JOIN roles ON roles.GroupId = skills.GroupId
OUTER APPLY
(
SELECT 1 SkillIsInRole
FROM @tbl_rolesskills rs
INNER JOIN @tbl_jobroles r ON rs.RoleID = r.ID
INNER JOIN @tbl_groupsskills gs ON gs.LinkID = rs.LinkID
INNER JOIN @tbl_groups g ON g.groupID = gs.GroupID
INNER JOIN @tbl_skills s ON s.skillID = gs.SkillID
WHERE s.SkillId = skills.SkillId
AND g.GroupId = skills.GroupId
AND r.Id = roles.RoleId
) t
ORDER BY roles.RoleTitle, skills.GroupTitle, skills.SkillTitle
修改:可以使用OUTER APPLY
LEFT JOIN
LEFT JOIN (
SELECT s.SkillId, g.GroupId, r.Id RoleId, 1 SkillIsInRole
FROM @tbl_rolesskills rs
INNER JOIN @tbl_jobroles r ON rs.RoleID = r.ID
INNER JOIN @tbl_groupsskills gs ON gs.LinkID = rs.LinkID
INNER JOIN @tbl_groups g ON g.groupID = gs.GroupID
INNER JOIN @tbl_skills s ON s.skillID = gs.SkillID
) t ON t.SkillId = skills.SkillId
AND t.GroupId = skills.GroupId
AND t.RoleId = roles.RoleId
答案 1 :(得分:1)
我认为你必须从一方准备一组所有可能的组合角色,从另一方面准备组技能。这是通过进行Decart乘法(通常由CROSS JOIN完成)来完成的。因此,您将获得每个角色的列表以及所有可能的群组技能组合的列表。之后,您可以使用表tbl_RolesSkills LEFT JOIN此结果。这将满足您的需求。您可以使用CTE或子查询来完成此操作。
必须看起来像this example
实际上不需要CROSS JOIN,我错过了“特定角色只有特定的群组”。只有一个子查询,也可以用CTE(公用表表达式)完成。
我也排除了“超级明星”角色。如果你想添加它,只需删除WHERE部分。