sql server 2008 CTE错误

时间:2014-07-17 09:20:58

标签: sql-server

我试图使用递归CTE,但我的查询进入无限循环。这是我的代码。这有什么问题?

With Family As 
( 
  Select s.EmpID, S.Name, s.RepID , 0 as Depth 
  From TestingRec s
  Where s.EmpID=s.RepID
  Union All 
  Select s2.EmpID,S2.Name, s2.RepID , Depth + 1
  From TestingRec s2
        Inner Join Family
        On s2.RepID = Family.EmpID

) 
Select *
From Family

3 个答案:

答案 0 :(得分:1)

从CTE的锚点部分:

Select s.EmpID, S.Name, s.RepID , 0 as Depth 
From TestingRec s
Where s.EmpID=s.RepID

我们可以看到TestingRec中有EmpIDRepID相等的行。在递归部分中,我们选择与我们已经找到的EmpID匹配的行:

Select s2.EmpID,S2.Name, s2.RepID , Depth + 1
From TestingRec s2
    Inner Join Family
    On s2.RepID = Family.EmpID

但是,这里没有任何内容可以阻止我们重新匹配锚点部分找到的那些行,并再次将它们添加到结果集中,只需指定新的深度。

修复可能就像递归部分中的WHERE子句一样简单s2.RepID <> s2.EmpID

答案 1 :(得分:1)

在第一个查询中,您将获得EmpId=RepId所有记录。当初始记录的手段empid和repid相等时。

然后在您的锚点查询(union all)中,您正在引用empid=family.repid,这意味着您还可以获得第一个查询结果。所以我认为你需要在第二个查询中排除第一级记录。以下查询可能有效

With Family As 
( 
  Select s.EmpID, S.Name, s.RepID , 0 as Depth 
  From TestingRec s
  Where s.EmpID=s.RepID
  Union All 
  Select s2.EmpID,S2.Name, s2.RepID , Depth + 1
  From TestingRec s2
        Inner Join Family
        On s2.RepID = Family.EmpID
  WHERE s2.RepID <> s2.EmpID

) 
Select *
From Family

答案 2 :(得分:1)

试试这个:

With Family As 
( 
 Select s.EmpID, S.Name, s.RepID , 0 as Depth 
 From TestingRec s
 Where s.EmpID=s.RepID
 Union All 
 Select s2.EmpID,S2.Name, s2.RepID , Depth + 1
 From TestingRec s2
 Inner Join Family
 On s2.RepID = Family.EmpID
 And s2.repid <> s2.empid --This excludes the results from the first half
) 

Select *
From Family