SQL CTE用于循环大小写

时间:2013-10-08 08:05:37

标签: sql sql-server sql-server-2008 tsql

我正在使用具有以下结构的会员资格表

GroupID  MemberType MemberID

   G1     user       U1
   G1     group      G2
   G2     user       U2
   G2     group      G3
   G3     group      G1

在这里,我的需要是......需要使用GroupID来获取群组成员..

对于直接会员,我们可以通过在查询位置使用GroupID列来轻松完成。

但要获得嵌套成员,我们需要递归执行此查询。为此,我使用了以下CTE查询。

;with cte as 
(
    select *, groupid as mastergroup,1 as level from mytable 
    union all       
    select t1.memberid, t1.membertype, null, cte.mastergroup, level+1
    from cte 
        inner join mytable t1
            on t1.groupid=cte.memberid
    where cte.membertype='group'
) 
select * from cte
where mastergroup='G1'

尼斯。如果嵌套组之间没有循环,它工作正常。但在我的情况下

我以这种方式拥有循环结构...... G1 - > G2 - > G3 - > G1 ...所以在这种情况下,我的查询在CTE循环中无限期运行。

能帮我解决这个案子吗?.....提前谢谢.....

1 个答案:

答案 0 :(得分:0)

我不确定下面的解决方案是否适合您,因为它不能完全解决理论上的循环问题,但在实践中它应该可行。

它依赖于这样一个事实,即你不能无限循环递归,但是你可以将它限制在某种程度 - 在我的例子中下面的100。这意味着它仍然会经历循环,但只要循环不是太长(总链< 99),它会正常工作并找到所有成员。

declare @mastergroup varchar(10) = 'G1'
declare @maxlevel int = 100

;with cte as 
(
    select groupid, memberid, membertype, 1 as level 
    from mytable1 
    where GroupID = @mastergroup

    union all     

    select t1.groupid, t1.memberid, t1.membertype, cte.level+1 as level
    from cte 
    inner join mytable1 t1
        on t1.groupid = cte.memberid
    and cte.level < @maxlevel
) 
select distinct groupid, memberid, membertype from cte
where MemberID <> @mastergroup