按显示顺序和 parent id 对列进行排序

order columns by display order and parent id

我有一个数据集,其中有一个行列表,每个行都有一个 ID、显示 order 和一个可为空的 parentID。如果他们有的话,我需要将它们按升序排列在 parent 后面。我不知道该怎么做。我正在考虑尝试一些工会,但需要的工会数量不受限制。

ID  order   parentID
4   1   
6   2   
5   1       6
1   2       6
7   3       6
77  3   
89  1       77
43  4   
23  5   
2   1       23
3   2       23

只需将您要排序的所有列放在 ORDER BY 子句中:

select parentID, ordering, ID
from mytab
order by parentID, ordering

(我已将 order 重命名为排序,因为 order 是 SQL 关键字)

更新

要将 NULL parentID 移动到底部,如果您的 RDBMS 支持,您可以使用 NULLS LAST

select parentID, ordering, ID
from mytab
order by parentID nulls last, ordering

您必须构建一个排序机制,以说明级别之间的排序以及每个级别内的排序。我将向您展示如何使用递归 CTE 执行此操作。

首先,您需要确定要比较的元素数量。在您的 table 中,答案最多为 5,但这可能是任意的。所以我们先查询一下

declare @dyn_ord as int = (select len(MAX(ordering)) from #A)

这会获取位数,在本例中仅为 1。在这里,我使用“#A”作为您的 table 的名称。

接下来,我们用我们想要的字段设置递归 CTE

declare @dyn_ord as int = (select len(MAX(ordering)) from #A)

; with
    Parent as (
    -- Anchor member definition
        select    a.Id -- of course show the ID
                , a.parentID -- show the parent's ID
                , cast(a.ID as varchar(max)) as Path -- this is bonus to help understand recursion
                , CAST((REPLACE(STR(ordering,@dyn_ord),' ','0')) AS nvarchar(max)) AS OrderString -- our modified ordering, explanation to follow
            from #A a
            where a.parentId is null
        union all
    -- Recursive member definition
        select    c.Id
                , c.parentID
                , cast(Path + ' -> ' + cast(c.ID as varchar(max)) as varchar(max)) as Path
                , (p.OrderString + '.' + CAST((REPLACE(STR(c.ordering,@dyn_ord),' ','0')) AS nvarchar(max))) AS OrderString
            from #A as c
            inner join Parent as p
                on c.parentID = p.ID
    )
SELECT    Id
        , parentID
        , Path
        , OrderString
    FROM Parent
    order by OrderString asc

OrderString 是我们用来订购的机制。在给定级别中,它 (1) 接受排序,(2) 将其转换为字符串,以及 (3) 根据需要填充任何额外的零。如果您尝试比较 1 和 10 之类的顺序,则需要第三步,这并不总能为您提供字符串比较所需的结果。

在递归步骤中,'OrderString' (1) 从父级获取已经存在的顺序,(2) 附加一个句点(不需要但有助于理解顺序),以及 (3) 然后执行与上一段中相同的三个步骤。