在这种情况下可以使用递归cte吗?

时间:2015-09-08 09:29:10

标签: sql sql-server tsql recursive-query

以下查询很好地满足了它的目的。我正在学习递归CTE并且没有轻松的时间去做。我想知道rCTE是否可以在这里使用?有人可以解释为什么或为什么不解释?这可能有助于我更好地理解这个概念。

以下是查询:

;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

1 个答案:

答案 0 :(得分:0)

如果您当前的查询效果很好,为什么要更改它?

您应首先考虑是否需要递归获取数据。然后,如果你真的需要一个递归过程,CTE可能是一个选项,而不是相反:意思是,你想要实现一个递归CTE,无论你是否需要递归数据。

递归CTE可以使用大量的资源,只应在需要时才使用,这是最好的选择。

  

下面的几个递归CTE,带有示例emplyee和manager表。

当您想要通过经理和员工表的层次结构进行递归浏览时,可以使用递归CTE。

如果你不知道谁在为这样的上帝之类的人工作,在层次结构的任何层面,你都可以使用这样的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个管理员。

如果您不想计算每位员工有多少员工,您可以使用这样的递归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