0

我写了一个 CTE 查询,这是我得到的结果

Item        Parent    Level  Group
--------------------------------------
CRSM/002    NULL        0   CRSM/002
7160/002    CRSM/002    1   CRSM/002
7823/085    CRSM/002    1   CRSM/002
7864/038    CRSM/002    1   CRSM/002
A543/033    CRSM/002    1   CRSM/002
7460/530    CRSM/002    1   CRSM/002
7280/007    7160/002    2   CRSM/002
7009/130    7160/002    2   CRSM/002
7567/001    7160/002    2   CRSM/002
7009/126    7160/002    2   CRSM/002
7280/003    7160/002    2   CRSM/002
7280/008    7160/002    2   CRSM/002
7280/005    7160/002    2   CRSM/002
7574/004    7160/002    2   CRSM/002
7280/004    7160/002    2   CRSM/002
7280/006    7160/002    2   CRSM/002
7454/224    7280/006    3   CRSM/002
7093/633    7280/006    3   CRSM/002
7202/010    7280/006    3   CRSM/002
7202/013    7280/004    3   CRSM/002
7454/253    7280/004    3   CRSM/002
7093/553    7280/005    3   CRSM/002
8865/957    7280/005    3   CRSM/002
7202/012    7280/005    3   CRSM/002
7093/696    7280/008    3   CRSM/002
7202/011    7280/008    3   CRSM/002
7454/294    7280/008    3   CRSM/002
7202/009    7280/003    3   CRSM/002
7454/201    7280/003    3   CRSM/002
7656/002    7009/126    3   CRSM/002
A556/075    7009/126    3   CRSM/002
7574/002    7009/126    3   CRSM/002
A902/027    7009/126    3   CRSM/002
7093/418    7280/007    3   CRSM/002
7454/245    7280/007    3   CRSM/002
7202/008    7280/007    3   CRSM/002

它正在返回具有所有层次结构、父子关系和根级别父分组的正确数据。

数据是正确的,但我希望数据以树结构排列,这意味着目前的排列就像这个 0 级行,然后是 1 级行的所有元素,依此类推......

我想要的安排是,首先是 0 级,然后是 1 级第一个孩子,如果那个孩子有孩子,那么那些孩子将在第二级等等。所以它将成为实际的树结构。我不知道我是否能够正确解释我的问题。我尝试过订购和其他组合,但未能成功。

有什么办法吗?

4

2 回答 2

3

请检查以下帖子父/子层次结构,如树视图

从SQL 递归 CTE 查询的代码中可以看出,我使用了深度(层次结构中的顺序)和排序列。排序列实际上提供了树视图。为了使可视化更清晰,我在层次结构中向下添加了 3 个空格字符

样本数据

declare @pc table(ID int, PARENT_ID int, [NAME] varchar(80));

insert into @pc
select 1,NULL,'Bill' union all
select 2,1,'Jane' union all
select 3,1,'Steve' union all
select 4,2,'Ben' union all
select 5,3,'Andrew' union all
select 6,NULL,'Tom' union all
select 7,8,'Dick' union all
select 8,6,'Harry' union all
select 9,3,'Stu' union all
select 10,7,'Joe';


; with r as (
    -- anchor part
      select ID, 
          PARENT_ID, 
          [NAME], 
          depth = 0 , 
          sort = convert(varchar(max), convert( char(10), ROW_NUMBER() over (order by ID)))
      from @pc
      where PARENT_ID is null

      union all

    -- recursive part
      select 
        pc.ID, 
        pc.PARENT_ID, 
        pc.[NAME], 
        depth = r.depth + 1, 
        sort = r.sort + convert( char(10), ROW_NUMBER() over (order by pc.ID))
      from r
      inner join @pc pc on r.ID=pc.PARENT_ID
)
select 
    space(depth*3) + name
from r
order by sort

输出如下

在此处输入图像描述

关于数据排序 在此处输入图像描述

于 2016-12-05T12:24:05.803 回答
2

只需要在构建过程中添加一个序列。

我在 Order By 中使用 ITEM,但您可以使用 Item Description 或其他演示顺序键(如果有)。

请参阅 DECLARE @Top 和 @Nest 中的注释。走着瞧吧

Declare @Table table (Item varchar(25), Parent varchar(25))
Insert into @Table values ('CRSM/002',NULL),('7160/002','CRSM/002'),('7823/085','CRSM/002'),('7864/038','CRSM/002'),('A543/033','CRSM/002'),('7460/530','CRSM/002'),('7280/007','7160/002'),('7009/130','7160/002'),('7567/001','7160/002'),('7009/126','7160/002'),('7280/003','7160/002'),('7280/008','7160/002'),('7280/005','7160/002'),('7574/004','7160/002'),('7280/004','7160/002'),('7280/006','7160/002'),('7454/224','7280/006'),('7093/633','7280/006'),('7202/010','7280/006'),('7202/013','7280/004'),('7454/253','7280/004'),('7093/553','7280/005'),('8865/957','7280/005'),('7202/012','7280/005'),('7093/696','7280/008'),('7202/011','7280/008'),('7454/294','7280/008'),('7202/009','7280/003'),('7454/201','7280/003'),('7656/002','7009/126'),('A556/075','7009/126'),('7574/002','7009/126'),('A902/027','7009/126'),('7093/418','7280/007'),('7454/245','7280/007'),('7202/008','7280/007')

Declare @Top  varchar(25) = null     --<<  Sets top of Hier Try '77009/126'
Declare @Nest varchar(25) ='|-----'  --<<  Optional: Added for readability

;with cteHB as (
      Select Seq  = cast(1000+Row_Number() over (Order by Item) as varchar(500))
            ,Item
            ,Parent
            ,Lvl=1
      From   @Table 
      Where  IsNull(@Top,'') = case when @Top is null then isnull(Parent,'') else Item end
      Union  All
      Select Seq  = cast(concat(p.Seq,'.',1000+Row_Number() over (Order by r.Item)) as varchar(500))
            ,r.Item
            ,r.Parent
            ,p.Lvl+1
      From   @Table r 
      Join   cteHB p on r.Parent = p.Item)
     ,cteR1 as (Select Seq,Item,R1=Row_Number() over (Order By Seq) From cteHB)
     ,cteR2 as (Select A.Seq,A.Item,R2=Max(B.R1) From cteR1 A Join cteR1 B on (B.Seq like A.Seq+'%') Group By A.Seq,A.Item )
Select B.R1  
      ,C.R2
      ,A.Item
      ,A.Parent
      ,A.Lvl
      ,Title = Replicate(@Nest,A.Lvl-1) + A.Item
 From cteHB A
 Join cteR1 B on A.Item=B.Item
 Join cteR2 C on A.Item=C.Item
 Order By B.R1,A.Seq

退货

在此处输入图像描述

编辑 - 我应该添加

范围键是可选的,如果不需要,只需删除 cteR1 和 cteR2。我使用这些非递归聚合的键。

编辑 - char(10) 的演示

使用转换(char(10),Row_Number() over (Order by r.Item)))

在此处输入图像描述

于 2016-12-05T12:31:42.963 回答