2015-09-08 62 views
-1

下面的查询很好地满足了它的用途。我正在学习递归CTE,而不是轻松做到这一点。我想知道rCTE是否可以在这里使用?有人可以解释为什么或为什么不?这可以帮助我更好地理解这个概念。在这种情况下可以使用递归cte?

下面是该查询:

;WITH a 
AS (
    SELECT u.user_login, m.user_id, m.mail_list_id 
    FROM users u 
    INNER JOIN mail_list_users m ON u.user_id = m.mail_list_id 

    ) 
SELECT a.user_login AS 'Mailing List', u1.user_login AS 'User Login' 
FROM a 
INNER JOIN users u1 ON a.user_id = u1.user_id 
ORDER BY a.user_login 
+0

这是一种很难说什么时候你不解释你想要达到的目标。 – JodyT

+0

@JodyT道歉。我有两个表:A)mail_list_id,它有两列,都有ID,特别是在经理 - 员工关系中(每个经理ID都有多个雇主ID)。表B是具有所有用户详细信息的用户表(如员工表)。目标是获得两列:经理姓名和员工姓名。我基本上想要mail_list_id表,而不是id我想要的名字。希望这可以清除事情。 – Crabster

+0

通常,如果您对管理员有不平衡的员工层次结构,那么您会在此处使用递归CTE。例如,如果您的员工与经理直接链接,并与另一位与小组负责人有联系的员工联系,小组负责人又与经理建立了联系。您将使用递归CTE来回溯“上游链”,直到找到实际经理,即将与员工/经理的关系变平。看起来你的数据不适合这一点,因为每个员工都已经与他们的经理有直接的联系。 –

回答

0

如果当前查询效果很好,你为什么要改变呢?

您应该首先考虑是否需要递归获取数据。然后,如果您确实需要递归过程,则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 

这里的水平表示在nameGod之间有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 
相关问题