Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/79.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在SQL中展平组成员关系树(使用循环引用)_Sql_Tsql - Fatal编程技术网

在SQL中展平组成员关系树(使用循环引用)

在SQL中展平组成员关系树(使用循环引用),sql,tsql,Sql,Tsql,我正在和一桌狗肉一起工作 GroupMembers(GroupName,MemberName) 每个组成员都有一行,一个组可以包含其他组和用户 我想提取GroupName和MemberName对的列表,其中MemberName只是一个用户列表。基本上,是把树压平。我以前也做过类似的事情,手动编写查询,将每个级别的叶子导出到一个单独的表中,然后在我达到最后一个级别后将其合并 树似乎不平衡,没有任何固定的级别数。我一直在看递归查询的例子,但在实现它们时运气不太好 有没有人能给我一个很好的建议,让我在

我正在和一桌狗肉一起工作

GroupMembers(GroupName,MemberName)

每个组成员都有一行,一个组可以包含其他组和用户

我想提取GroupName和MemberName对的列表,其中MemberName只是一个用户列表。基本上,是把树压平。我以前也做过类似的事情,手动编写查询,将每个级别的叶子导出到一个单独的表中,然后在我达到最后一个级别后将其合并

树似乎不平衡,没有任何固定的级别数。我一直在看递归查询的例子,但在实现它们时运气不太好

有没有人能给我一个很好的建议,让我在哪里找到一个优雅的解决方案

非常感谢

ps如果有帮助,我正在使用SQL Server 2008

更新:我偶然发现了递归CTE。我唯一的问题是数据中存在循环引用:(.

这是我用于查询的代码:-

    WITH Members AS
    (
    --Init
    SELECT GroupName, MemberName
    FROM GroupMembers
    WHERE MemberName NOT IN (Select GroupName from GroupMembers)
    UNION ALL

    --Recursive Exe
    SELECT h.GroupName, h.MemberName
    FROM GroupMembers h INNER JOIN Members m
    ON h.MemberName = m.GroupName
    )
    Select * into GroupMembersFlattened from Members OPTION (MAXRECURSION 1500)
在执行上述查询之前,是否有方法排除循环引用/clense数据

谢谢

循环/循环参考示例 循环引用的一个示例是数据包含以下内容:-

    GroupMember,     MemberName
    Group1,     Group2
    Group1,     User1
    Group2,     Group3
    Group2,     User2
    Group3,     Group1
谢谢你的小费,米克尔

我想提取一份 组名、成员名对,其中 MemberName只是一个用户列表

我可能不理解你的结构,但对我来说,你只需要这样做

SELECT GroupName, MemberName
FROM GroupMembers
WHERE MemberName NOT IN (Select GroupName from GroupMembers)
这将为您提供所有叶节点。如果组可以是叶,或者如果用户可以有成员,则需要其他内容来区分用户和组

结果与您的样本数据一致:

GroupName   MemberName
---------   ----------
Group1      User1
Group2      User2

这就是排除循环的方式

WITH Members AS
(
--Anchor
SELECT 
    GroupName, 
    MemberName,
    0 As isCycle,
    '.' + CAST(MemberName As varchar(max)) + '.' As [path]
FROM GroupMembers
WHERE 
    MemberName NOT IN (Select GroupName from GroupMembers)

UNION ALL

--Recursive call
SELECT 
    h.GroupName, 
    h.MemberName,
    CASE WHEN m.[path] like  '%.' + CAST(h.MemberName as varchar(max)) + '.%' THEN 1 ELSE 0 END As isCycle,
    m.[path] + CAST(h.MemberName as varchar(max)) + '.' As [path]
FROM GroupMembers h 
    JOIN Members m
        ON h.MemberName = m.GroupName
WHERE
    m.isCycle = 0
)
SELECT  
    * 
FROM 
    Members
WHERE
    Members.isCycle = 0

如果您可以提供一些带有循环引用的示例输入数据以及预期输出应该是什么,这将非常有用。因此,在上面的示例中,组1、2和3应该被视为同一组,对吗?并且
User1
User2
都应该属于所有
Group1
Group2
Group3
?嘿,JP,我只是想说一下,但你能将你的选择定义为不同的吗?我不确定,但这可能会停止递归。我只是想了想Thello Magnus,谢谢你的回答。我实现了你的解决方案,它工作得很好。我使用路径字段提取了t顶部父组的用户名和组名ree。再次感谢您的输入和如此快速的回复。你好,Mikael,感谢您的回复。我遇到的问题是,我需要从树的顶部列出一个父组列表,然后是它们的扩展叶用户列表。我可以看到您的建议,但我认为只有在嵌套为1级时才有效深度。在使用Magnus的解决方案后,我发现在我的数据中,内塞廷的深度从1级到8级不等。感谢您的输入,非常感谢。