Sql 使用具有不明确联接的查找表的递归视图

Sql 使用具有不明确联接的查找表的递归视图,sql,sql-server,tsql,sql-server-2012,Sql,Sql Server,Tsql,Sql Server 2012,我甚至不知道如何命名这个问题,但我希望这是有意义的 我有三张桌子: 用户及其详细信息表 组表及其详细信息 组表,其成员的查找ID来自“用户”或“组”表 第三个表有两列: 与组(第二个)表中的行匹配的组ID 与用户(第1个)或组(第2个)表中的行匹配的成员ID 注: 用户和组表的ID相互之间是唯一的。例如,如果一个用户的ID=1,则其他用户或任何组都不会具有相同的ID 一个组可以有一个用户或另一个组作为成员 我需要转储第三个表的视图,完全扩展每个组的所有成员,包括嵌套组,转储组路径,并处理无限

我甚至不知道如何命名这个问题,但我希望这是有意义的

我有三张桌子:

  • 用户及其详细信息表
  • 组表及其详细信息
  • 组表,其成员的查找ID来自“用户”或“组”表
  • 第三个表有两列:

  • 与组(第二个)表中的行匹配的组ID
  • 用户(第1个)或组(第2个)表中的行匹配的成员ID
  • 注:

    • 用户和组表的ID相互之间是唯一的。例如,如果一个用户的ID=1,则其他用户或任何组都不会具有相同的ID
    • 一个组可以有一个用户或另一个组作为成员
    我需要转储第三个表的视图,完全扩展每个组的所有成员,包括嵌套组,转储组路径,并处理无限循环。希望这个例子能说明这一点:

    1.使用者 2.组 3.小组成员 4.输出/结果 这里有一个答案和一个


    “要么”呃……真正有帮助的是一些以CREATETABLE和insert语句的形式提供的可消费数据。这是一个很好的起点。当你得到“[递归]”时,我不知道这里的逻辑是什么。这是什么意思?组路径值在这里有什么意义?问题是什么?关于递归查询的现有帖子不包含您需要的信息吗?我没有看到任何研究成果。您应该添加一个类似于“我尝试了这个,我得到了这个,但不知道怎么做”的部分。在我看来,“请为我写我的查询”的问题太宽泛了。@Sean:你所说的可消费数据是什么意思?让我再补充一些你提到的细节。@Tab:我的问题是“我需要转储第三个表的视图…”部分。我试过其他问题,但找不到类似的问题。也许我找错东西了。我会补充一些细节。。。
    | ID | user_name |
    |----|-----------|
    |  1 | one       |
    |  2 | two       |
    |  3 | three     |
    |  4 | four      |
    |  5 | five      |
    
    | ID | group_name |
    |----|------------|
    |  6 | six        |
    |  7 | seven      |
    |  8 | eight      |
    |  9 | nine       |
    | 10 | ten        |
    
    | group_ID | member_ID |
    |----------|-----------|
    |        6 |         1 |
    |        6 |         2 |
    |        6 |         3 |
    |        7 |         4 |
    |        7 |         5 |
    |        8 |         1 |
    |        8 |         9 |
    |        8 |        10 |
    |        9 |         5 |
    |       10 |         1 |
    |       10 |         8 |
    
    | group_ID | user_ID | user_name   | group_path
    |----------|---------|-------------|------------
    |        6 |       1 | one         | six
    |        6 |       2 | two         | six
    |        6 |       3 | three       | six
    |        7 |       4 | four        | seven
    |        7 |       5 | five        | seven
    |        8 |       1 | one         | eight
    |        8 |       5 | five        | eight > nine
    |        8 |       1 | one         | eight > ten
    |        8 |         | [recursive] | eight > ten > eight
    |        9 |       5 | five        | nine
    |       10 |       1 | one         | ten
    |       10 |       1 | one         | ten > eight
    |       10 |       5 | five        | ten > eight > nine
    |       10 |         | [recursive] | ten > eight > ten
    
    ;with cte as 
    (
    select id,name=user_name, type='U' from users
    union
    select  id, name=group_name, type='G' from groups
    )
    , cte2 as 
    (
        select 
            user_id=c.id, 
            user_name=c.name,
            group_Id=g.group_ID,
            group_path= cast(c2.name as nvarchar(max))
        from cte c 
        left join [group members] g 
            on g.member_id=c.id and type='U'
        left join cte c2  
            on c2.type='G' and c2.id=g.group_ID
        union all
        select 
            user_id=user_id, 
            user_name=user_name,
            group_Id=g.group_ID,
            group_path= concat(c2.name,'>',c.group_path)
        from cte2 c
            join [group members] g 
            on g.member_id=c.group_Id
           join cte c2
           on g.group_ID=c2.id and c2.type='G'
            where c.group_path not like '%'+c2.name+'%'  
     )
     select 
         group_id,
         user_id,
         user_name, 
         group_path 
     from cte2
     where group_id is not null
     union all
     select 
         group_id=g.group_ID,
         user_id= NULL,
         user_name='[recursive]',
         group_path=concat(c2.name,'>',c.group_path)
     from cte2 c 
     join [group members] g
         on g.member_id=c.group_Id
         join cte c2
           on g.group_ID=c2.id and c2.type='G'
            where c.group_path like '%'+c2.name+'%'
      order by group_id,user_id