假设这张table
ParentId ChildId SortOrder --------------------------------- 0 1 0 1 2 1 2 3 1 2 4 2 2 6 3 1 7 2 1 9 3 9 10 1 9 12 2
我将如何编写简单的CTE(或其他类型的查询),以在任何级别返回它们的父/子关系,但将所有子项的排序顺序保持在父项之下。
基本上,这将是一个简单的树视图,其中的子项目按特定的排序顺序进行排序。
SQL Server 2008是数据库
更新:可以有无限个父级/子级-我尝试了其他堆栈问题/答案中的一些示例,但没有一个在子级中包含排序顺序。
示例结果应为:
parent (sort 0) child (sort 1) child (sort 2) child (sort 3) child-child (sort 1) child (sort 4) child-child (sort 1) child-child (sort 2)
等等。
希望这是有道理的-也许我正在看这个错误,这样的结果最好在中间层构建?
无论如何,任何反馈都将不胜感激
具有特殊排序覆盖的递归CTE。请注意2的子级中的排序覆盖(我对源表进行了少许修改以测试此功能)
declare @relations table(ParentID int, ChildID int, SortOrder int, treeID int); insert into @relations values (0,1,0,0), (1,2,1,0), (2,3,2,0), (2,4,1,0), (2,6,3,0), (1,7,2,0), (1,9,3,0), (9,10,1,0), (9,12,2,0) --tree 0 , (0,1,0,1), (1,2,1,1), (2,3,2,1), (2,4,1,1), (2,6,3,1), (1,7,2,1), (1,9,3,1), (9,10,1,1), (9,12,2,1) --tree 1 ; with cte(ParentId,ChildId,SortOrder,depth,agg,treeID) as ( select null,ParentId,SortOrder,0 , right('0000000'+CAST(treeID as varchar(max)),7) +right('0000000'+CAST(SortOrder as varchar(max)),7) , treeID from @relations where ParentId=0 union all select cte.ChildId,r.ChildId,r.SortOrder,cte.depth+1 , cte.agg +right('0000000'+CAST(r.treeID as varchar(max)),7) +right('0000000'+CAST(r.SortOrder as varchar(max)),7) +right('0000000'+CAST(r.ChildId as varchar(max)),7) , r.treeID from cte inner join @relations r on r.ParentID=cte.ChildId where cte.depth<32767 and r.treeID=cte.treeID ) select tree=case depth when 1 then cast(ParentID as varchar(30))+' (sort '+cast(SortOrder as varchar(30))+')' else REPLICATE(CHAR(9),depth-1) + cast(ChildId as varchar(30))+' (sort '+cast(SortOrder as varchar(30))+')' end from cte where depth>0 order by agg option (maxrecursion 32767);
结果:
tree -------------------------------------------------- 0 (sort 0) 2 (sort 1) 4 (sort 1) 3 (sort 2) 6 (sort 3) 7 (sort 2) 9 (sort 3) 10 (sort 1) 12 (sort 2) 0 (sort 0) 2 (sort 1) 4 (sort 1) 3 (sort 2) 6 (sort 3) 7 (sort 2) 9 (sort 3) 10 (sort 1) 12 (sort 2)