1

以下の構造のメンバーシップテーブルがあります

GroupID  MemberType MemberID

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

ここで、私のニーズは.. GroupID を使用してグループ メンバーを取得する必要がある..

Direct members の場合、 where クエリで 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 ループで無期限に実行されます。

このケースを解決するために私を助けることができますか?.....事前に感謝します.....

4

1 に答える 1

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
于 2013-10-08T09:05:20.007 に答える