3

我尝试使用创建 SQL 语句,WITH但我无法正确使用。

我得到了以下表格;

组(ID、名称)

1, 'My app'
2, 'Local admins'
3, 'Global admins'

用户(1,姓名)

1, 'Arne'

GroupOwners(GroupId、OwnerType、OwnerId)

1, 'Group', 2

GroupMembers (GroupId、MemberType、MemberId)

2, 'Group', 3
3, 'User', 1

我正在尝试查找所有Arne属于其所有者的组。在这种情况下,它是My App. 但问题是Local Admins被设置为所有者。并且Global adminsLocal admins. 并Arne终于成为Global admins.

在此处输入图像描述

没关系钻石,它们是不正确的

嵌套因组而异。(有些用户直接在 GroupOwners 中,而其他用户可能有一个用户作为成员的组)

是否可以用一个 SQL 语句的母亲来解决?附加约束:Groups/Users在系统的其他地方使用。

4

2 回答 2

4

这是递归 cte,它将首先找到组Arno是其中的成员,然后匹配所有直接或间接包含这些组的组。结果最终加入到 GroupOwners 以限制结果。注意:如果Arno可能是组的所有者,但不是该组的成员,则此查询也需要 UNION 来附加这些组。

declare @UserID int = 1

; with allTheGroups as (
  select gm.GroupID
    from GroupMembers gm
   where gm.MemberType = 'User'
     and gm.MemberID = @UserID
  union all
  select gm.GroupID
    from GroupMembers gm
   inner join allTheGroups
      on gm.MemberID = allTheGroups.GroupID
   where gm.MemberType = 'Group'
)
select Groups.*
  from Groups
 inner join GroupOwners gow
    on Groups.ID = gow.GroupID
   and gow.OwnerType = 'Group'
 inner join allTheGroups a
    on gow.OwnerID = a.GroupID

带有示例的 Sql Fiddle 在这里

用于检索直接拥有添加的组的用户的联合示例。需要附加到上面的查询(当然选择列表调整)。

union
select gow.OwnerID, Users.Name
  from GroupOwners gow
 inner join Users
    on gow.OwnerID = Users.ID
   and gow.OwnerType = 'User'
 where gow.OwnerID = @UserID
于 2012-08-28T08:06:06.980 回答
-2

是的,您的表格建模不正确。你只需要有两张桌子。组和管理员(或用户,取决于您的方案)。

然后,您将诸如“本地”或“全局”或名称 (Arne) 之类的内容存储在 Admin/User 表中。然后它只是两个表之间的简单选择或连接。无需嵌套/递归。

如果您需要我为您绘制 ERD 或其他内容来解释,请告诉我。

于 2012-08-28T06:32:43.150 回答