Sql server 如何从SQL Server检索已排序的分层数据

Sql server 如何从SQL Server检索已排序的分层数据,sql-server,tsql,hierarchical-data,recursive-query,Sql Server,Tsql,Hierarchical Data,Recursive Query,我见过很多分级CTE的例子,但我还不能正确地进行排序 为了描述我的问题,假设此任务表: TaskId ParentTaskId Label a10 null 10 a20 null 11 a30 a20 18 a50 a30 5 a40 a20 15 a60 null 12

我见过很多分级CTE的例子,但我还不能正确地进行排序

为了描述我的问题,假设此任务表:

TaskId    ParentTaskId    Label
a10       null            10
a20       null            11
a30       a20             18
a50       a30             5
a40       a20             15
a60       null            12
查询的输出应按标签和子标签排序,如下所示:

Sequence   TaskId       Label
1          a10          10
2          a20          11
3            a40        15
4            a30        18
5              a50       5
6          a60          12
我添加了缩进以便于您注意分组。a40和a30是a20的子代,根据标签订购

请帮忙。谢谢

以下是答案:

drop table if exists #t
go

select
    *
into
    #t
from
(
    values 
        ('a10', null, '10'),
        ('a20', null, '11'),
        ('a30', 'a20', '18'),
        ('a50', 'a30',  '5'),
        ('a40', 'a20', '15'),
        ('a60', null, '12')
) as T(TaskId, ParentTaskId, Label)
;

with cte as
(
    select 
        l = 0, 
        p = cast('/' + Label as nvarchar(max)), 
        * 
    from 
        #t where ParentTaskId is null

    union all

    select 
        l = p.l + 1, 
        p = p.p + '/' + c.Label, 
        c.* 
    from 
        #t c 
    inner join 
        cte p on c.ParentTaskId = p.TaskId
)
select
    *
from
    cte
order by p, Label
您需要创建从任务根到当前任务的路径,然后使用它对最终结果进行排序。 在小数据集上,上述查询将执行良好。关于更大的(几十万),我建议看一下
hierarchyid
数据类型:


从您的示例数据中不清楚
标签是字符串还是整数,即
'5'
'10'
之后还是
5
10
之前?@HABO-Label是整数。谢谢!因为
p
总是以
Label
p排序结束,所以Label
是多余的,
p
就足够了。对,我没有注意到。我在第一次测试中没有使用label来构建路径,而是使用TaskId,这就是为什么我按p和label排序。在最后的测试中忘了删除它。谢谢你的回答@GusCavalcanti解释说,
Label
是一个
int
这个答案需要做一些工作。组合到
p
中的值需要在左侧以固定长度进行零填充,即
/5
将在
/10
之后进行alpha排序,但填充到五位的
/00005
将在
/00010
之前进行排序。