按显示顺序和父ID排序列

时间:2017-03-07 21:22:50

标签: sql sql-order-by

我有一个数据集,其中我有一个行列表,每个行都有一个ID,显示order和一个可空的parentID。我需要以升序显示顺序返回它们,如果它们有父级,则按其父级分组。我不知道怎么回事。我正在考虑尝试一些工会,但是需要一些未结合的工会。

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

2 个答案:

答案 0 :(得分:1)

您必须构建一个排序机制,该机制考虑级别之间的排序以及每个级别内的排序。我将向您展示如何使用递归CTE来完成它。

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

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

这会得到位数,在这种情况下只是1.这里,我使用'#A'作为你的桌子的名字。

接下来,我们使用我们想要的字段设置递归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)然后执行与前一段相同的三个步骤。

答案 1 :(得分:0)

只需在ORDER BY子句中输入要排序的所有列:

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

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

<强>更新

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

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