我们有一个系统,用户从服务目录中选择一个角色,并将角色映射到目标系统中某些组的成员资格。
某些角色的组重叠,而某些角色由另一个角色的完整子集组实现。
后者导致我出现问题。我不知道如何只提取超级套装。
Role Grps
Role1 GrpA
Role1 GrpB
Role1 GrpC
Role2 GrpA
Role2 GrpB
Role3 GrpA
Role3 GrpD
Usr Grps
User1 GrpA
User1 GrpB
User2 GrpA
User2 GrpB
User2 GrpC
User3 GrpA
User3 GrpD
User4 GrpD
需要输出
Usr Role
User1 Role2
User2 Role1
User3 Role3
而不是
Usr Role
User1 Role2
User2 Role1
User2 Role2
User3 Role3
答案 0 :(得分:1)
对于[tblRoleGrps]
中的测试数据Role Grps
----- ----
Role1 GrpA
Role1 GrpB
Role1 GrpC
Role2 GrpA
Role2 GrpB
Role3 GrpA
Role3 GrpD
和[tblUsrGrps]
Usr Grps
----- ----
User1 GrpA
User1 GrpB
User2 GrpA
User2 GrpB
User2 GrpC
User3 GrpA
User3 GrpD
User4 GrpD
我们可以在Access中创建一个名为[qryRoleGrpCounts]的已保存查询,该查询为我们提供了属于每个角色的组的数量
SELECT Role, COUNT(*) AS GrpCount
FROM tblRoleGrps
GROUP BY Role
返回
Role GrpCount
----- --------
Role1 3
Role2 2
Role3 2
对于名为[qryUsrGrpCounts]的已保存查询的用户,我们可以做同样的事情
SELECT Usr, COUNT(*) AS GrpCount
FROM tblUsrGrps
GROUP BY Usr
返回
Usr GrpCount
----- --------
User1 2
User2 3
User3 2
User4 1
我们还可以创建一个名为[qryUsrRoleMatches]的查询,该查询计算用户与可能所属角色之间的匹配数量
SELECT ug.Usr, rg.Role, COUNT(*) AS MatchCount
FROM tblUsrGrps ug INNER JOIN tblRoleGrps rg ON ug.Grps = rg.Grps
GROUP BY ug.Usr, rg.Role
返回
Usr Role MatchCount
----- ----- ----------
User1 Role1 2
User1 Role2 2
User1 Role3 1
User2 Role1 3
User2 Role2 2
User2 Role3 1
User3 Role1 1
User3 Role2 1
User3 Role3 2
User4 Role3 1
使用这些保存的查询,我们可以构建其他查询以查找用户和角色之间的匹配。例如,列出存在“完全匹配”的实例,意思是......
用户和角色(qryUserRoleMatches.MatchCount)之间的匹配数正是该用户的组数(qryUsrGrpCounts.GrpCount)以及相应角色的组数(qryRoleGrpCounts.GrpCount)。
......我们可以使用
SELECT qurm.Usr, qurm.Role
FROM
(
qryUsrRoleMatches qurm
INNER JOIN
qryUsrGrpCounts qugc
ON qurm.Usr = qugc.Usr
AND qurm.MatchCount = qugc.GrpCount
)
INNER JOIN
qryRoleGrpCounts qrgc
ON qurm.Role = qrgc.Role
AND qurm.MatchCount = qrgc.GrpCount
返回
Usr Role
----- -----
User1 Role2
User2 Role1
User3 Role3
答案 1 :(得分:0)
在T SQL(SQL Server)查询中可以写成:
with cte_servicecatalogue as
(
select sc1.UserId,
STUFF(ISNULL((SELECT ', ' + sc.Grps
FROM servicecatalogue sc
WHERE sc.UserId = sc1.UserId
--GROUP BY sc.UserId
FOR XML PATH (''), TYPE).value('.','VARCHAR(max)'), ''), 1, 2, '') [Groups]
from servicecatalogue sc1
GROUP BY sc1.UserId
)
,cte_RoleMembership as
( select RM1.Role,
STUFF(ISNULL((SELECT ', ' + RM.Grps
FROM RoleMembership RM
WHERE RM.Role = RM1.Role
--GROUP BY sc.UserId
FOR XML PATH (''), TYPE).value('.','VARCHAR(max)'), ''), 1, 2, '') [Groups]
from RoleMembership RM1
GROUP BY RM1.Role
)
select cte1.UserId, cte2.Role
from cte_servicecatalogue cte1
inner join cte_RoleMembership cte2 on cte1.[Groups] = cte2.[Groups]
order by UserId
检查演示here..