递归SQL查询,但不是通常的递归类型

时间:2013-07-05 18:12:40

标签: sql sql-server recursion recursive-query

我有一组表将一组人组织成团队。

  • 用户(ID int PK等)
  • 团队(ID int PK等)
  • UsersToTeams(ID int PK,UserID int FK,TeamID int FK,TeamSupervisor bit not null)

表中没有父ID,因为用户可以在任意数量的团队中,团队可以拥有任意数量的主管。用户可能在六个团队中,但仅监督其中两个,并且这些受监督团队中的一个或两个可能还有其他监督员。所以我的层次结构看起来更像是一个网络,而不是一棵树。

我认识到递归查询可能会导致循环引用。假设软件暂时正在处理它。

公司层级由监督用户团队的监督员,监督监督员团队的经理等描述。所以它是分层的,但不是通常的方式。

我需要一个查询,给定一个UserID,将返回他监督的用户的ID,下降到无限级别。这样的查询怎么可能?

实施例

Users (ID, Name)
1 Archie
2 Betty
3 Chuck
4 Dilton
5 Eddie
6 Fannie

用户1是经理(级别3)。用户2和3是主管(级别2)。用户4,5,6是用户(级别1)。

Teams (ID, Name)
1 Team Alpha
2 Team Bravo
3 Sup Team

UsersToTeams (ID INT PK, UserID INT FK, TeamID INT FK, isSupervisor BIT)
1 1 3 1  -- Archie supervises Sup Team
2 2 3 0  -- Betty is a member of Sup Team
3 3 3 0  -- Chuck is a member of Sup Team
4 2 1 1  -- Betty supervises team Alpha
5 4 1 0  -- Dilton is a member of team Alpha
6 5 1 0  -- Eddie is a member of team Alpha
7 3 2 1  -- Chuck supervises Team Bravo
8 6 2 0  -- Fannie is a member of Team Bravo
  • Archie是一名经理,负责监督一个监督团队。
  • 贝蒂是一名主管,负责监督用户团队。
  • Chuck是一名监督,负责监督用户团队。
  • 贝蒂和查克在Archie的团队中也是 ,但不要监督它。

因此:

  1. 如果我通过UserID 5(Eddie),我应该只回来5,因为Eddie没有监督任何人。
  2. 如果我传入UserID 3(Chuck),我应该回到3和6,因为Fannie在Chuck监督的团队中。
  3. 如果我传入UserID 1(Archie),我应该取回此处描述的所有UserID,因为Betty和Chuck在Archie的团队中,其他人都在Betty的团队或Chuck的团队中。
  4. 对不起,我尝试了SQL小提琴链接,但在“构建架构”15分钟后,我对此失去了希望。

1 个答案:

答案 0 :(得分:2)

您可以使用递归CTE执行此操作。

首先,选择用户自己,然后递归选择他立即监督的所有用户:

declare @userID int = 1;

with u as (
  select id from users where id = @userID
  union all
  select lacky.userID from u supervisor
  join usersToTeams supervising on supervising.userID = supervisor.id and isSupervisor = 1
  join usersToTeams lacky on lacky.teamID = supervising.teamID and lacky.isSupervisor = 0
)

select * from u

这是小提琴:http://www.sqlfiddle.com/#!3/525e1/3