Evi*_*lDr 5 t-sql sql-server sql-server-2012
几天来我一直在苦苦挣扎,如果我过度混淆了事情,那么道歉......
我有一系列表定义:
数据库的结构如下所示:
我需要创建一个显示以下数据的结果集:
对于所有工作角色,显示这些工作角色中的所有技能.但是,还包括各个组中未包含在每个角色中的技能(用NULL或任何其他方法表示).
请参阅此工作代码以创建表和数据. SQL Fiddle
Apologies的长度,我做了很多插入来创建一个现实的例子.
请注意,该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
Run Code Online (Sandbox Code Playgroud)
获取与角色相关的团队的所有技能有些简单,并在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
Run Code Online (Sandbox Code Playgroud)
编辑: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
Run Code Online (Sandbox Code Playgroud)