2

ユーザー、グループ、メンバーシップの 3 つのテーブルがあります。
ユーザーには ID と名前があります。
グループには ID と名前もあります。
メンバーシップには ID、GroupId、およびMemberIdがあります

問題は、MemberIdがユーザーとグループの両方になることができるということです

私が望むのは、ユーザーが直接または属していないすべてのグループを取得することです。

これを行うには、以下に示すように CTE を使用しています。

WITH MyGroups AS(
select *,1 as GLevel from [Group] as g where g.id IN (SELECT groupId FROM Membership m where m.memberId='MYID')

UNION ALL

select g.*,2 from [Group] g inner JOIN MyGroups my on my.id=g.id --where g.id IN (SELECT groupId FROM ACLTests.dbo.Membership m where m.groupid=g.id))

Select * from MyGroups

しかし、私は100レベルの再帰を超えています...誰か助けてくれますか?

サンプルデータ:

ユーザー テーブル:
ID ----------|タイトル---------
myUser1 |John
myUser2 |Leo

グループ テーブル:
ID---------|タイトル---------
myG1 . . .|
グループ1 myG2 . . .|グループ2

メンバーシップ テーブル:
ID | グループ ID | メンバーID
01 | myG1.. . . .| myUser1
02 | myG1.. . . .| myG2
03 | myG2.. . . .| MyUser2

MyUser1の予期される結果: Group1 MyUser2 の予期される
結果: Group1、Group2 (G2 は g1 のメンバーであり、User2 は G2 のメンバーであるため、User2 も G1 のメンバーです)

4

2 に答える 2

1

ここに必要なクエリがあります。本当に必要なoption (maxrecursion 0)場合は、それを以下のクエリにも追加してください。

    SET NOCOUNT ON
    DECLARE @User TABLE
    (
        id      sysname NOT NULL
        ,title  sysname NOT NULL
    )
    DECLARE @Groups TABLE
    (
        id      sysname NOT NULL
        ,title  sysname NOT NULL
    )
    DECLARE @Membership TABLE
    (
        id      INT NOT NULL
        ,groupid    sysname NOT NULL
        ,memberid   sysname NOT NULL
    )

    INSERT INTO @User( id, title ) SELECT 'myuser1','John' UNION ALL SELECT 'myuser2','Leo'
    INSERT into @Groups( id, title ) SELECT 'myG1','Group1' UNION ALL SELECT 'myG2','Group2'
    INSERT into @Membership( id, groupid, memberid ) SELECT 1,'myG1','myuser1' UNION ALL SELECT 2,'myG1','myG2' UNION ALL SELECT 3,'myG2','myuser2'



    DECLARE @SearchUsergroup sysname='myUser2'
    ;WITH mType(id,title,mType)
    AS
    (
        SELECT id,title,'user' AS mType
        FROM @User
        UNION ALL
        SELECT id,title,'Group' AS mType
        FROM @Groups
    ),
    Ugroups(id,mType,mLevel)
    AS
    (
        SELECT groupid,'Group' as mType, 1 AS mLevel
        FROM @Membership
        WHERE memberid = @SearchUsergroup

        UNION ALL
        SELECT ms.groupid,'Group' as mType, ug.mLevel+1 AS mLevel
        FROM mType mt
        JOIN Ugroups ug
            ON mt.id=ug.id AND ug.mType='Group'
        JOIN @Membership ms
            ON ms.memberid=ug.id
    )
    SELECT id AS GroupID,mLevel AS MembershipLevel
    FROM Ugroups

ここに画像の説明を入力

于 2013-10-25T16:58:05.240 に答える
0

option (maxrecursion 0)クエリの最後に追加します。

アップデート。

WITH MyGroups AS (
    select g.id, 1 as GLevel
    from Group as g
    where g.id IN (
        SELECT groupId
        FROM Membership m
        where m.memberId = 'MyUser2'
    )
    UNION ALL
    select m.GroupId, my.GLevel + 1
    from Membership m
    inner JOIN MyGroups my on m.memberId=my.id
)

Select * from MyGroups
于 2013-10-25T14:06:15.160 に答える