我有一个查询来获取组中的成员列表,如下所示
;WITH CTE (GroupName, GroupMember, isMemberGroup)
AS (SELECT ag.name,
agm.Member,
agm.MemberIsGroup
FROM tb1 ag
LEFT JOIN tb2 agm
ON ag.ID = agm.ID
WHERE ag.name = 'somegroupame')
SELECT *
FROM CTE
Group Name Group Member IsMemberGroup
Admin John 0
Admin Sam 0
Admin GDBA 1
xyz Dan 0
xyz GXy 1
如果IsMemberGroup为1,我想写一个查询来获取子组的成员。请指导我如何实现这一目标。
预期结果是获取成员列表,包括给定组的子组成员。递归应该发生在所有子组中。团体也是如此:
结果:管理员
Group Group Member
Admin John
Admin Sam
Admin(GDBA) Mike
Admin(GDBA) June
Admin(GDBA/Bcksdmin)Mark
答案 0 :(得分:1)
您可以使用recursive CTE来生成群组成员层次结构来解决此问题。
此示例使用以下数据:
/* Let's create some sample data to experiment with.
*/
DECLARE @Sample TABLE
(
GroupName VARCHAR(50),
GroupMember VARCHAR(50),
IsMemberGroup BIT
)
;
INSERT INTO @Sample
(
GroupName,
GroupMember,
IsMemberGroup
)
VALUES
('Admin', 'John', 0),
('Admin', 'Sam', 0),
('Admin', 'GDBA', 1),
('GDBA', 'Mike', 0),
('GDBA', 'June', 0),
('GDBA', 'Bcksdmin', 1),
('Bcksdmin', 'Mark', 0)
;
查询使用CTE计算组层次结构。然后将其连接回原始数据,如下所示:
/* Using a recursive CTE we can build the group name
* hierarchy.
*/
WITH [Group] AS
(
/* Anchor query returns all top level teams, ie
* those that do not appear in the group member
* field.
*/
SELECT
s1.GroupName,
CAST(s1.GroupName AS VARCHAR(MAX)) AS Breadcrumb
FROM
@Sample AS s1
LEFT OUTER JOIN @Sample AS s2 ON s2.GroupMember = s1.GroupName
WHERE
s2.GroupName IS NULL
GROUP BY
s1.GroupName
UNION ALL
/* Using recursion, find all children.
* (Sub groups are identified by the IsMemberGroup flag).
*/
SELECT
s.GroupMember AS GroupName,
g.Breadcrumb + '/' + s.GroupMember
FROM
[Group] AS g
INNER JOIN @Sample AS s ON s.GroupName = g.GroupName
WHERE
s.IsMemberGroup = 1
)
SELECT
g.Breadcrumb,
s.GroupMember
FROM
@Sample AS s
INNER JOIN [Group] AS g ON g.GroupName = s.GroupName
WHERE
s.IsMemberGroup = 0
;
虽然这个解决方案有效,但如果可能的话,我建议您重新访问表格设计。 GroupMember专栏通过存储团队和团队成员来实现双重任务。将其拆分为Group(带有父查找列)和GroupMember表可以简化任务。每个新表只需要描述一个真实世界对象,使得创建新列的位置更加清晰。