2010-08-19 59 views
2

有3個數據庫中的表:一個一對多視圖中的SELECT語句

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

如何創建用戶表的視圖,這將有IsAdmin欄,這裏是一個樣機:

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應該是(1)如果用戶在 「管理員」 用戶角色和(0),如果他不

+0

我的意思是..什麼是最有效的方法 - 就像我的例子或有更好的方法? – 2010-08-19 18:37:19

回答

0

我自己的解決方案看起來更好。

1

試試這個

她e是另一種方式......但我喜歡的EXISTS版本,查爾斯BRETANA貼好

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

我以爲他們想要平坦的結果。 – ChaosPandion 2010-08-19 17:59:16

+0

如果有多個角色附加到同一用戶,它會工作嗎? – 2010-08-19 18:00:14

+0

你在哪裏看到的?所有它說的是「IsAdmin應該是(1)如果用戶在」管理員「用戶角色和(0)如果他不是」 – SQLMenace 2010-08-19 18:00:23

1

嘗試:

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

這項工作是否有效?避免在VIEW中使用嵌套的SELECT語句不是更好嗎? – 2010-08-19 18:05:36

+0

那麼,我很少會指望一個查詢的語法版本比另一個更有效或更低效地運行。查詢處理器/優化器在實際執行方面具有很大的自由度,它所具有的各種選項大多由索引和統計數據決定,而不是從構建SQL的方式來確定。只要sql在邏輯上一致,就選擇一個最清楚表達你的意圖的方法。 – 2010-08-19 20:02:41

0

添加另一列到你的角色表,isAdmin,並將其設置爲true僅限Admin角色。然後,在視圖中,檢查where子句中的isAdmin標記。

1

該方法奏效。注意添加新的角色檢查是多麼微不足道。

代碼

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 

結果

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