如果当前查询效果很好,你为什么要改变呢?
您应该首先考虑是否需要递归获取数据。然后,如果您确实需要递归过程,则CTE可能是一种选择,而不是其他方式:意思是说,无论您是否需要递归数据,您都希望实现递归CTE。
递归CTE可以使用很多资源,它只能在需要时使用,它是最好的选择。
下面有一对夫妇递归CTE,带有示例emplyee和manager表。
当您想通过管理员和员工表的层次递归浏览时,可以使用递归CTE。
如果你wan't知道谁是工作的人这样一个上帝之下,在层次结构的任何级别,就可以使用这样的CTE:
Declare @data table(id int, name varchar(10), manager int)
insert into @data(id, name, manager) values
(0, 'God', null)
, (1, 'John', 0)
, (2, 'Bob', 1)
, (3, 'Lisa', 0)
, (4, 'Jorg', 1)
, (5, 'Mike', 3)
, (6, 'Nick', 5);
with cte(level, id) as (
Select 0, id From @data Where manager in (Select id From @data Where name = 'God')
Union All
Select level+1, d.id From @data d
Inner Join cte c on c.id = d.manager
)
Select c.level, d.name, manager = m.name
From cte c
Inner Join @data d on d.id = c.id
Inner Join @data m on d.manager = m.id
Order by level
输出:
level name manager
0 John God
0 Lisa God
1 Mike Lisa
1 Bob John
1 Jorg John
2 Nick Mike
这里的水平表示在name
和God
之间有N个管理员。
如果你wan't计算有多少员工正在努力为每一位员工,你可以使用递归CTE像这样的:
with cte(level, id, manager) as (
Select 0, id, id From @data
Union All
Select level+1, c.id, d.id From @data d
Inner Join cte c on c.manager = d.manager
)
Select d.name, employees = count(*)-1
From cte c
Inner Join @data d on d.id = c.id
Group By d.name
OPTION(MAXRECURSION 0)
输出:
name employees
Bob 0
God 6
John 2
Jorg 0
Lisa 2
Mike 1
Nick 0
这是一种很难说什么时候你不解释你想要达到的目标。 – JodyT
@JodyT道歉。我有两个表:A)mail_list_id,它有两列,都有ID,特别是在经理 - 员工关系中(每个经理ID都有多个雇主ID)。表B是具有所有用户详细信息的用户表(如员工表)。目标是获得两列:经理姓名和员工姓名。我基本上想要mail_list_id表,而不是id我想要的名字。希望这可以清除事情。 – Crabster
通常,如果您对管理员有不平衡的员工层次结构,那么您会在此处使用递归CTE。例如,如果您的员工与经理直接链接,并与另一位与小组负责人有联系的员工联系,小组负责人又与经理建立了联系。您将使用递归CTE来回溯“上游链”,直到找到实际经理,即将与员工/经理的关系变平。看起来你的数据不适合这一点,因为每个员工都已经与他们的经理有直接的联系。 –