SQL ORDER BY by sibling value

时间:2018-03-16 10:55:03

标签: sql sql-server sql-server-2008

我有两列,其名称为idsibling_id,类型为uniqueidentifier我想通过id以编程方式排序sibling_id。我的数据结构如下,因此值可以改变。

id                                      sibling_id
------------------------------------    ------------------------------------
4146831B-79FA-6EB4-981B-FF00002477F7    78068B1B-79FA-6EB4-981B-FF00002477F7
53058B1B-79FA-6EB4-981B-FF00002477F7    00000000-0000-0000-0000-000000000000
5B058B1B-79FA-6EB4-981B-FF00002477F7    30718C1B-79FA-6EB4-981B-FF00002477F7
78068B1B-79FA-6EB4-981B-FF00002477F7    5B058B1B-79FA-6EB4-981B-FF00002477F7
80068B1B-79FA-6EB4-981B-FF00002477F7    4146831B-79FA-6EB4-981B-FF00002477F7
30718C1B-79FA-6EB4-981B-FF00002477F7    53058B1B-79FA-6EB4-981B-FF00002477F7

预期ORDER BY如下

Order   id                                      sibling_id
------  ------------------------------------    ------------------------------------
1       53058B1B-79FA-6EB4-981B-FF00002477F7    00000000-0000-0000-0000-000000000000
2       30718C1B-79FA-6EB4-981B-FF00002477F7    53058B1B-79FA-6EB4-981B-FF00002477F7
3       5B058B1B-79FA-6EB4-981B-FF00002477F7    30718C1B-79FA-6EB4-981B-FF00002477F7
4       78068B1B-79FA-6EB4-981B-FF00002477F7    5B058B1B-79FA-6EB4-981B-FF00002477F7
5       4146831B-79FA-6EB4-981B-FF00002477F7    78068B1B-79FA-6EB4-981B-FF00002477F7
6       80068B1B-79FA-6EB4-981B-FF00002477F7    4146831B-79FA-6EB4-981B-FF00002477F7

1 个答案:

答案 0 :(得分:1)

您可以使用recursive CTE获取订购:

;WITH TraverseTree AS (
   -- Anchor query: get root node
   SELECT 1 as [order], id, sibling_id   
   FROM mytable AS t
   WHERE NOT EXISTS (SELECT 1
                     FROM mytable AS x
                     WHERE x.id = t.sibling_id)

   UNION ALL

   -- Recursive query: get node of next level
   SELECT  t2.[order] + 1 AS [order], t1.id, t1.sibling_id  
   FROM mytable AS t1
   JOIN TraverseTree AS t2 ON t1.sibling_id = t2.id
)
SELECT *
FROM TraverseTree
ORDER BY [order]

CTE首先选择根节点,即没有父节点的记录。根据提供的样本数据,此记录为:

53058B1B-79FA-6EB4-981B-FF00002477F7    00000000-0000-0000-0000-000000000000

然后重复执行递归查询,直到它没有返回任何记录。首次执行时,会选择上一条记录的子记录:

30718C1B-79FA-6EB4-981B-FF00002477F7    53058B1B-79FA-6EB4-981B-FF00002477F7

等等,直到遍历了整个树。

注意:字段名称sibling_id有点误导。在我看来应该称之为father_id

Demo here