2014-07-11 2 views
1

Nous avons un système dans lequel les utilisateurs sélectionnent un rôle dans le catalogue de services et le rôle est mappé à l'appartenance à certains groupes du système cible.Requête SQL pour trouver le rôle de superset

Il existe un chevauchement des groupes entre certains rôles et certains rôles sont remplis par un groupe qui est un sous-ensemble complet d'un autre rôle.

C'est ce dernier qui me pose problème. Je ne sais pas comment extraire le super ensemble.

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 

Résultat requis

Usr Role 
User1 Role2 
User2 Role1 
User3 Role3 

Plutôt que

Usr Role 
User1 Role2 
User2 Role1 
User2 Role2 
User3 Role3 
+0

Ce qui SGBDR parlons-nous ici? Serveur SQL? –

+1

Je le fais dans MS Access – happyolly

+0

Vous voudrez peut-être le marquer avec 'ms-access', Access prend en charge un sous-ensemble très limité de SQL, donc une solution SQL peut ne pas vous aider beaucoup. –

Répondre

0

dans la requête TSQL (SQL Sever) peut être écrit:

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 

check Démo here..

+0

Merci, je vais jeter un coup d'oeil à ce détail dans un moment mais je ne vois pas où vous empêchez les résultats d'inclure des rôles de "sous-ensemble". – happyolly

+0

Ce que j'ai fait ici est dans le premier CTE que j'ai regroupé les utilisateurs et créé une chaîne séparée par des virgules de tous les groupes auxquels appartient l'utilisateur. De même dans le second CTE, j'ai regroupé les rôles et créé une chaîne séparée par des virgules de tous les groupes que le rôle contient. Ensuite, il a apparié les deux virgules séparées pour obtenir le résultat souhaité. – Deepshikha

+0

Mais la solution est dans T-SQL et je viens de vérifier les commentaires où vous avez mentionné que vous avez besoin de solution dans MS Access. – Deepshikha

1

Pour les données de test dans [tblRoleGrps]

Role Grps 
----- ---- 
Role1 GrpA 
Role1 GrpB 
Role1 GrpC 
Role2 GrpA 
Role2 GrpB 
Role3 GrpA 
Role3 GrpD 

et [tblUsrGrps]

Usr Grps 
----- ---- 
User1 GrpA 
User1 GrpB 
User2 GrpA 
User2 GrpB 
User2 GrpC 
User3 GrpA 
User3 GrpD 
User4 GrpD 

nous pouvons créer une requête enregistrée dans Access nommé [qryRoleGrpCounts] qui nous donne le nombre de groupes qui appartiennent à chaque rôle

SELECT Role, COUNT(*) AS GrpCount 
FROM tblRoleGrps 
GROUP BY Role 

retour

Role GrpCount 
----- -------- 
Role1   3 
Role2   2 
Role3   2 

Nous pouvons faire la même chose pour les utilisateurs avec une requête enregistrée nommée [qryUsrGrpCounts]

SELECT Usr, COUNT(*) AS GrpCount 
FROM tblUsrGrps 
GROUP BY Usr 

retour

Usr GrpCount 
----- -------- 
User1   2 
User2   3 
User3   2 
User4   1 

Nous pouvons également créer une requête nommée [qryUsrRoleMatches] qui compte le nombre des correspondances entre les utilisateurs et les rôles auxquels ils appartiennent

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 

retour

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 

Avec ces requêtes enregistrées à notre disposition, nous pouvons construire d'autres requêtes pour trouver des correspondances entre les utilisateurs et les rôles. Par exemple, pour lister les cas où il y a une « correspondance exacte », ce qui signifie ...

Le nombre de correspondances entre un utilisateur et un rôle (qryUserRoleMatches.MatchCount) est précisément le nombre de groupes pour cet utilisateur (qryUsrGrpCounts.GrpCount) et exactement le nombre de groupes pour le rôle correspondant (qryRoleGrpCounts.GrpCount).

...nous pouvons utiliser

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 

retour

Usr Role 
----- ----- 
User1 Role2 
User2 Role1 
User3 Role3 
Questions connexes