Tsql 视图中的一对多SELECT语句

Tsql 视图中的一对多SELECT语句,tsql,Tsql,数据库中有3个表: Users (UserID, UserName), Roles(RoleID, RoleName) and UserRoles(UserID, RoleID) 如何在Users表上创建具有IsAdmin列的视图,下面是一个模型: CREATE VIEW UsersView AS SELECT u.UserID, u.UserName, CASE WHEN ur.RoleID IS NULL THEN (0) ELSE

数据库中有3个表:

Users (UserID, UserName), Roles(RoleID, RoleName) and UserRoles(UserID, RoleID)
如何在Users表上创建具有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
如果用户处于“Admins”用户角色,则IsAdmin应为(1);如果用户不是,则IsAdmin应为(0)

请尝试以下操作

这是另一种方式…但我确实喜欢Charles Bretana发布的
EXISTS
版本

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
尝试:


向角色表中添加另一列isAdmin,并仅针对管理员角色将其设置为true。然后,在视图等中,检查where子句中的isAdmin标记。

这种方法有效。请注意,添加新角色检查是多么微不足道

代码

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 UserID用户名IsAdmin IsGenius 2吉姆0 1菲尔11 3苏珊10
我自己的解决方案看起来更好。

我以为他们想让结果更简单。如果有多个角色附加到同一个用户上,它会起作用吗?你在哪里看到的?它所说的是“如果用户是“Admins”用户角色,IsAdmin应该是(1)如果他不是(0)”+1:如果OP希望添加对其他角色的支持,则是最可伸缩的选项。在真实用户表中,除了UserID、UserName之外,还有很多其他列。。由所有人进行分组至少看起来可疑,而且可能没有效率。这样做有效吗?避免在视图中使用嵌套的SELECT语句不是更好吗?嗯,我很少指望一个查询的语法版本比另一个查询的操作效率更高或更低。查询处理器/优化器在如何实际执行这件事上有很大的自由度,它拥有的大多数选项更多地取决于索引和统计信息,而不是SQL的构造方式。只要sql在逻辑上是一致的,就选择一个最清楚地表达您意图的sql。。最有效的方法是什么?像我的例子中那样,还是有更好的方法? UserID UserName IsAdmin IsGenius 2 Jim 0 0 1 Phil 1 1 3 Susan 1 0