我有一个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
才能看到正确的结构( sibling unsorted )。< / p>
但是 - 我的order by
应该是怎样的,这样我才能看到正确的结构(&amp;&amp; sibling sorted )?
(在我的示例中:d
应该在c
之前)
Here is the working query which yields all the tree leafs ( unsorted siblings)
P.S。 childID
不表示有关排序的任何信息。它只是一个占位符。正如我所说,2兄弟之间的位置是location
列。(这里,childId被排序,因为这是我插入行的顺序......
答案 0 :(得分:5)
您可以计算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
答案 1 :(得分: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
注意:未经测试并在度假时写作。
分隔符(.
)不是必需的,但可以使结果值更易于阅读,并且可以简化某些操作,例如:找到共同的子路径。