2015-04-14 2 views
1

В Microsoft SQL Server, следующие работы, но производит:реверсивный порядок сортировки КТР

, сын, папа, дедушка, прадедушка

тогда мне нужно сказать:

прадедушка, дедушка, папа, сын

declare @Family Table(
ID Int Identity(100,1) Primary Key 
,Person varchar(128) 
,ParentID Int default 0 

) 
insert into @Family(Person,ParentID) values('Great Granddad',0) 
insert into @Family(Person,ParentID) values('Granddad',100) 
insert into @Family(Person,ParentID) values('Dad',101) 
insert into @Family(Person,ParentID) values('Son',102) 
DECLARE @ID Int = 103 
;with cte1 as (
    select 
     @ID AS cteID 
     ,ID 
     ,ParentID 
     ,Person as ctePerson 
    from @Family 
    where ID = @ID -- this is the starting point you want in your recursion 
    UNION ALL 
    select @ID, F.ID, F.ParentID, F.Person 
    from @Family F 
    join cte1 P on P.ParentID = F.ID -- this is the recursion 
) 
-- cte2 can reverse the sort order based on something built in (OVER?) 
-- ROW_NUMBER() OVER(ORDER BY ? DESC) AS Row 

,cte3 AS(
    select ID as cte3ID,(
     SELECT ',' + ctePerson 
     FROM cte1 
     WHERE cteID = F.ID 
     FOR XML PATH ('') 
     ) as People 
    from @Family F 
    where [email protected] 
) 
SELECT * FROM CTE3 

ответ

2

Я бы не заказывал результат рекурсивного CTE с использованием другого CTE, так как результаты CTE являются семантическими таблицами, и поэтому заказ не гарантируется. Вместо этого заказывайте при выборе из CTE, просто как обычные таблицы.

Я хотел бы предложить, чтобы вставить поле, представляющее уровень или отношения и порядок на что:

;with cte1 as (
    select 
     @ID AS cteID 
     ,ID 
     ,ParentID 
     ,Person as ctePerson 
     ,0 lvl -- starting level with 0 
    from @Family 
    where ID = @ID -- this is the starting point you want in your recursion 
    UNION ALL 
    select @ID, F.ID, F.ParentID, F.Person 
    , lvl + 1 -- increase level by 1 
    from @Family F 
    join cte1 P on P.ParentID = F.ID -- this is the recursion 
) 

,cte3 AS(
    select ID as cte3ID,STUFF((-- stuff removes the first ',' 
     SELECT ',' + ctePerson 
     FROM cte1 
     WHERE cteID = F.ID 
     ORDER by lvl DESC -- order by level DESC to start with latest ancestor 
     FOR XML PATH ('') 

     ), 1, 1, '') as People 
    from @Family F 
    where [email protected] 
) 
SELECT * FROM CTE3 
+0

Человек, который так приятно. –

Смежные вопросы