获取左侧或右侧基于二叉树的{anststor

时间:2017-02-10 17:10:06

标签: sql sql-server binary-tree

我有一个存储二叉树的表,如下所示:

Id   ParentId Level Placement 
47   -1       0     0
23   47       1     0
86   47       1     1
5    23       2     0
29   23       2     1
68   86       2     0
8    5        3     1
31   29       3     1
67   68       3     0
.
.
.

使用MSSQL 我需要给出parentId和childId的sql,它告诉parentId它是在左侧还是右侧。 例如

FindPoistion(parentId:47,childId:34)返回左侧

FindPoistion(parentId:23,childId:8)返回左

FindPoistion(parentId:29,childId:30)返回正确的

FindPoistion(parentId:47,childId:5)返回左

FindPoistion(parentId:47,childId:62)返回权限 FindPoistion(parentId:47,childId:86)返回正确的

如何编写一个基于ancenstor给我位置的sql?

左上方的位置为0,右侧为

enter image description here

这是我到目前为止所拥有的

    WITH name_tree
     AS (SELECT Id,
                Parentid,
                 Placement               
         FROM   BinaryTree
         WHERE  Parentid = 47 and Id= 31
         -- this is the starting point you want in your recursion
         UNION ALL
         SELECT c.Id,
                c.Parentid,
                c.Placement

         FROM   BinaryTree c
                JOIN name_tree p
                  ON p.Id = c.ParentId -- this is the recursion
                     AND c.Id <> c.Parentid

                     )
SELECT distinct Id, parentId, Placement 

FROM   name_tree 

1 个答案:

答案 0 :(得分:2)

Declare @YourTable table (id int,ParentId  int)
Insert into @YourTable values  (47,-1),(23,47),(86,47),( 5,23),(29,23),(68,86),( 8, 5),(31,29),(67,68),(62,67),(30,31),(34,31),(42,34),(40,42)

Declare @Top    int         = 47 
Declare @Fetch  int         = 31 

;with cteP as (
      Select ID
            ,ParentId 
            ,Level=1
      From   @YourTable 
      Where  ID=@Fetch
      Union  All
      Select r.ID
            ,r.ParentId 
            ,p.Level+1
      From   @YourTable r
      Join   cteP p on r.ParentId  = p.ID)
Select ID = @Top
      ,ParentID = -1
      ,Level = 0
      ,Placement = 0
Union All
Select A.ID
      ,ParentID = case when A.Level=1 then @Top else A.ParentId end
      ,A.Level
      ,Placement = case when A.Level=1 then IIF(A.ID<@Top,0,1) 
                   else case when IsNull(B.ID,A.ParentId) < A.ID then 1 else 0
                   end end
From cteP A
Left  Join cteP B on (A.ParentId=B.ParentId and B.ID<> A.ID)

<强>返回

enter image description here

以下返回

Declare @Top    int         = 47 
Declare @Fetch  int         = 31 

enter image description here