2010-08-19 4 views
2

Il y a 3 tables dans une base de données:One-to-Many instruction SELECT dans une vue

Users (UserID, UserName), Roles(RoleID, RoleName) and UserRoles(UserID, RoleID) 

Comment créer une vue sur la table des utilisateurs qui ont colonne IsAdmin, voici un mockup:

CREATE VIEW UsersView AS 
    SELECT 
     u.UserID, 
     u.UserName, 
     CASE WHEN ur.RoleID IS NULL THEN (0) ELSE (1) END AS IsAdmin 
    FROM Users AS u 
     LEFT JOIN Roles AS r ON r.RoleName = N'Admins' 
     LEFT JOIN UserRoles AS ur ON ur.UserID = u.UserID 
            AND ur.RoleID = r.RoleID 

IsAdmin doit être (1) si l'utilisateur est en rôle d'utilisateur "Admins" et (0) s'il ne

+0

Je veux dire ... quelle serait la façon la plus efficace de le faire - comme dans mon exemple ou il y a un meilleur moyen? –

Répondre

0

Mes propres solutions semble mieux.

1

essayer cette

Son e est une autre façon ... mais je aime la version EXISTS que Charles Bretana a affiché une meilleure

CREATE VIEW UsersView AS 
SELECT UserID,UserName, MAX(IsAdmin) as IsAdmin 
FROM(SELECT 
    u.UserID, 
    u.UserName, 
    CASE r.RoleName when 'Admins' then 1 else 0 end AS IsAdmin 
FROM Users AS u 
    LEFT JOIN UserRoles AS ur ON ur.UserID = u.UserID 
    LEFT JOIN Roles r on ur.RoleID = r.RoleID) x 
    GROUP BY UserID,UserName 
+0

Je pensais qu'ils voulaient aplatir le résultat. – ChaosPandion

+0

Cela fonctionnera-t-il si plusieurs rôles sont attachés au même utilisateur? –

+0

où voyez-vous cela? Tout ce qu'il dit est "IsAdmin devrait être (1) si l'utilisateur est dans" Admins "rôle de l'utilisateur et (0) s'il n'est pas" – SQLMenace

1

essayer:

CREATE VIEW UsersView AS 
    SELECT 
     u.UserID, 
     u.UserName, 
     Case When Exists 
      (Select * from userRoles ur 
       Join Roles r On r.RoleId = ur.Roleid 
      Where ur.userId = u.UserId 
       And r.RoleName = '"Admins') 
      Then 1 Else 0 End IsAdmin 
    FROM Users u 
+0

Est-ce que cela fonctionnera efficacement? Ne vaudrait-il pas mieux éviter d'utiliser l'instruction SELECT imbriquée dans une VUE? –

+0

Eh bien, je compterais rarement sur une version syntaxique d'une requête pour fonctionner plus ou moins efficacement qu'un autre. Le processeur/optimiseur de requête a une grande latitude dans la façon dont il exécute réellement la chose de toute façon, et la plupart des différentes options qu'il a sont déterminées plus à partir des indices et des statistiques que de la façon dont vous avez construit le SQL. Tant que le sql est logiquement cohérent, choisissez celui qui exprime le plus clairement votre intention. –

0

Ajouter une autre colonne à votre table des rôles, isAdmin et mis à true uniquement pour le rôle Admin. Ensuite, dans les vues et autres, recherchez le marqueur isAdmin dans la clause where.

1

Cette approche a fonctionné. Notez qu'il est trivial d'ajouter de nouveaux contrôles de rôle.

code

Declare @Users Table(UserID Int, UserName VarChar(256)) 
Declare @Roles Table(RoleID Int, RoleName VarChar(256)) 
Declare @UserRoles Table(UserID Int, RoleID Int) 

Insert Into @Roles Select 1, 'Admins' 
Insert Into @Roles Select 2, 'Role2' 
Insert Into @Roles Select 3, 'Role3' 
Insert Into @Roles Select 4, 'Genius' 

Insert Into @Users Select 1, 'Phil' 
Insert Into @UserRoles Select 1, 1 
Insert Into @UserRoles Select 1, 2 
Insert Into @UserRoles Select 1, 3 
Insert Into @UserRoles Select 1, 4 

Insert Into @Users Select 2, 'Jim' 
Insert Into @UserRoles Select 2, 2 
Insert Into @UserRoles Select 2, 3 

Insert Into @Users Select 3, 'Susan' 
Insert Into @UserRoles Select 3, 1 
Insert Into @UserRoles Select 3, 2 
Insert Into @UserRoles Select 3, 3 


Select UserID, 
     UserName, 
     Cast([Admins] As Bit) As IsAdmin, 
     Cast([Genius] As Bit) As IsGenius 
From (
    Select Users.UserID, 
      Users.UserName, 
      Roles.RoleName 
    From @Users As Users 
     Left Join @UserRoles As UserRoles On UserRoles.UserID = Users.UserID 
     Left Join @Roles As Roles On UserRoles.RoleID = Roles.RoleID 
) As Data 
Pivot (
    Count(RoleName) For RoleName In (
     [Admins], [Genius] 
    ) 
) As Result 

Résultat

 
UserID UserName IsAdmin IsGenius 
2  Jim  0  0 
1  Phil  1  1 
3  Susan 1  0 
Questions connexes