我有一个CTE递归查询,正在寻找每个孩子的根父母。在正常情况下,根父级的ParentID应为null。但是,如果“root parent”(请参阅下面的childID 4)具有应该位于同一层次结构下的ParentID,则会创建一个无限循环。
正常情况
ChildID ParentID StartDate Root Parent
1 2 2014 4
2 3 2013 4
3 4 2012 4
4 NULL 2011 4
5 6 2012 6
6 NULL 2013 6
无限循环
ChildID ParentID StartDate Root Parent Desired Root Parent
1 2 2014 4 1
2 3 2013 1 1
3 4 2012 2 1
4 1 2011 3 1
5 6 2012 6 6
6 6 2013 6 6
我创建了以下查询来停止无限循环,但是ChildID为1,2,3和4的根父母都是不同的。我的目标是根据StartDate(分配最新的)将Root parent 1分配给ChildID 1,2,3和4。
我不知道从哪里开始。任何帮助将不胜感激。感谢。
With a as
( select 1 as childID, 2 as ParentID, 2014 as startDate
union all select 2 as childID, 3 as ParentID , 2013 as startDate
union all select 3 as childID, 4 as ParentID, 2012 as StartDate
--union all select 4 as childID, NULL as ParentID, 2011 as StartDate
union all select 4 as childID, 1 as ParentID, 2011 as StartDate
union all select 5 as childID, 6 as ParentID, 2012 as StartDate
union all select 6 as childID, NULL as ParentID, 2013 as StartDate
)
, RCTE AS
( SELECT childID
, ParentID
, 1 AS Lvl
, '/' + convert(varchar(max), rtrim(childID)) + '/' [path]
, startDate
from a
UNION ALL
SELECT rc.childID
, rh.ParentID
, Lvl+1 AS Lvl
, rc.[path] + convert(varchar(max),rtrim(rh.childID)) + '/'
, rc.startDate
FROM a rh
INNER JOIN RCTE rc ON
rh.childID = rc.ParentID and
rh.childID<>rh.ParentID
WHERE rc.[path] not like '%/' + convert(varchar(max),rtrim(rh.ParentID)) + '/%'
)
, CTE_RN AS
( SELECT *
, ROW_NUMBER() OVER (PARTITION BY r.childID ORDER BY r.Lvl DESC) RN
FROM RCTE r
)
SELECT r.childID,
case
when r.ParentID is null then childID
else ParentID
end as ParentID
, rn,[path]
, r.startDate
FROM CTE_RN r
WHERE RN=1
Order by ChildID, RN