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,则其他用户或任何组都不会具有相同的ID
- 一个组可以有一个用户或另一个组作为成员
“要么”呃……真正有帮助的是一些以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