4

我有一个 CTE 查询,用于查找主叶和子叶。但我无法控制2 个兄弟姐妹之间的叶子选择顺序:

表中的每一行都声明为:

(childID INT ,parentID INT ,NAME NVARCHAR(30),location int)

location优先排序IFF他们是兄弟姐妹的优先级在哪里。

所以我有这个树结构:这些对有一个位置优先级:

在此处输入图像描述

例如 :

`a` ( location=1) should be before `f` (location=2)
`b` ( location=1) should be before `e` (location=2)
`d` ( location=1) should be **before** `c` (location=2)

问题是我似乎必须首先 order by childID看到正确的结构(未排序的兄弟)。

但是 - 我order by应该是什么样子才能看到正确的结构(&& 兄弟排序)?

(在我的例子中:d应该在之前c

这是产生所有树叶(未排序的兄弟姐妹)的工作查询

pschildID没有说明任何关于排序的内容。它只是一个占位符。正如我所说,两兄弟之间的位置是按location列排列的。(在这里,childId 是排序的,因为那是我插入行的顺序......

4

2 回答 2

6

您可以计算 CTE 中树节点的路径并将其用于排序

;WITH CTE AS(
   SELECT childID, parentID, 0 AS depth, NAME , location,
         cast(location as varbinary(max)) path
   FROM   @myTable
   WHERE   childID = parentID 
    UNION ALL
    SELECT  TBL.childID, TBL.parentID,
           CTE.depth + 1 , TBL.name ,TBL.location,
           cte.path + cast(TBL.location as binary(4))
    FROM   @myTable AS TBL
            INNER JOIN CTE  ON  TBL.parentID = CTE.childID
    WHERE   TBL.childID<>TBL.parentID
)
SELECT depth, childID, parentID, location, REPLICATE('----', depth) + name
FROM CTE
ORDER BY path
于 2013-08-03T19:35:07.053 回答
3

以下是根据 Royi Namir 的要求修改的 i-one 的答案,以使用左侧填充的数字字符串作为路径:

;WITH CTE AS(
   SELECT childID, parentID, 0 AS depth, NAME , location,
         Cast( Right( '00000' + Cast( Location as VarChar(6) ), 6 ) as  VarChar(1024) ) as Path
   FROM   @myTable
   WHERE   childID = parentID 
    UNION ALL
    SELECT  TBL.childID, TBL.parentID,
           CTE.depth + 1 , TBL.name ,TBL.location,
           Cast( cte.Path + '.' + Right( '00000' + Cast( Tbl.Location as VarChar(6) ), 6 ) as VarChar(1024) )
    FROM   @myTable AS TBL
            INNER JOIN CTE  ON  TBL.parentID = CTE.childID
    WHERE   TBL.childID<>TBL.parentID
)
SELECT depth, childID, parentID, location, REPLICATE('----', depth) + name
FROM CTE
ORDER BY path

注意:未经测试且在假期中编写。

分隔符 ( .) 不是必需的,但可以使结果值更易于阅读,并且可以简化一些操作,例如查找公共子路径。

于 2013-08-04T11:52:28.260 回答