SQL Server With子句递归如何在查询级别内部工作

时间:2015-02-27 16:55:06

标签: sql sql-server

我一直在使用此查询来识别,如何以递归方式运行查询。

CREATE Table #Temp1
(
    Deptno int, 
    ename Varchar(50),
    eno int
)

Insert into #Temp1(ename, Deptno, eno) Values('John', 10, 1)
Insert into #Temp1(ename, Deptno, eno) Values('Audrey', 10, 2)
Insert into #Temp1(ename, Deptno, eno) Values('Jackson', 10, 3)
Insert into #Temp1(ename, Deptno, eno) Values('Tommyy', 20, 4)
Insert into #Temp1(ename, Deptno, eno) Values('Johniee', 20, 5)
Insert into #Temp1(ename, Deptno, eno) Values('William', 20, 7)
Insert into #Temp1(ename, Deptno, eno) Values('Audreeee', 30, 6) 

with x (deptno, cnt, names, eno, len) as 
(
    select deptno, count(*) over (partition by deptno),
        cast(ename as varchar(100)),
        eno, 1
    from #Temp1

    union all

    select x.deptno, x.cnt,
        cast(x.names + ',' + e.ename as varchar(100)),
        e.eno, x.len+1
    from #Temp1 e, x
    where e.deptno = x.deptno and e.eno > x.eno
)
select 
    deptno, names, cnt, len, eno
from x 
where len = cnt
order by 1

结果集

10  John    3   1   1
10  Audrey  3   1   2
10  Jackson 3   1   3
20  Tommyy  3   1   4
20  Johniee 3   1   5
20  William 3   1   7
30  Audreeee    1   1   6
20  Johniee,William 3   2   7
20  Tommyy,Johniee  3   2   5
20  Tommyy,William  3   2   7
20  Tommyy,Johniee,William  3   3   7
10  Audrey,Jackson  3   2   3
10  John,Audrey 3   2   2
10  John,Jackson    3   2   3
10  John,Audrey,Jackson 3   3   3

使用子句递归查询:

从上面的查询中我对该查询中串联的发生方式完全感到困惑。

假设前7行是锚点查询的结果集。我需要从该结果中知道第二个查询如何处理结果集。

特别是deptno:10,20

需要详细说明。

1 个答案:

答案 0 :(得分:0)

列表是这一行的结果:

cast(x.names + ',' + e.ename as varchar(100)),

您的递归部分的执行次数与部门中人员数量eno低于同一部门其他人的人数相同。

因此对于部门10,首先您可以按照建议从查询的顶部(锚点)中自己获取每个人。

然后您获得John,AudreyJohn,JacksonAudrey,Jackson,因为您要将ename的{​​{1}}添加到eno更高的enoeno。你得到一个迭代,它会得到你所有三个名字,因为它们都有不同的;WITH cte AS (SELECT 1 AS num UNION ALL SELECT num + 1 FROM cte WHERE num < 5 ) SELECT * FROM cte 值。

也许一个不同的例子会有所帮助:

以下输出1-5的数字,锚执行一次,然后递归部分执行,直到没有更多的记录满足标准:

{{1}}