父级和子级的大纲编号列

时间:2013-10-10 14:56:52

标签: sql sql-server sql-server-2005

将db表的大纲编号设为:

PID    Task    OutlineNumber
------------------------------
1      Task1       0
2      Task2       1
3      Task3       1.1
4      Task4       1.1.1
5      Task5       2
6      Task6       2.1
7      Task7       2.1.1

我想将此数据选为:

PID    Task     CatID SubCatID
------------------------------
1      Task1     0      NULL
2      Task2     1       1
3      Task3     1       2
4      Task4     1       3
5      Task5     2      NULL 
6      Task6     2       5
7      Task7     2       6

我正在使用SQLExpress 2005

1 个答案:

答案 0 :(得分:0)

由于我们还不知道OutlineNumber的深度,我将提供一个解决方案,该解决方案基于我使用parsename通常订购的4部分版本号:

;with VNums as (
    select PID
        , Task
        , OutlineNumber
        , OutlineNumber + replicate('.0', 3 - (len(OutlineNumber) - len(replace(OutlineNumber, '.', '')))) as VNum
    from MyTable
), VOrders as (
    select PID
        , Task
        , OutlineNumber
        , VNum
        , row_number() over (order by cast(parsename(VNum, 4) as int), cast(parsename(VNum, 3) as int), cast(parsename(VNum, 2) as int), cast(parsename(VNum, 1) as int)) as VOrder
    from VNums
)
select PID
    , Task
    , parsename(VNum, 4) as CatID
    , case when OutlineNumber not like '%.%' then null else VOrder - 1 end as SubCatID
from VOrders
order by VOrder;

这会产生:

PID    Task     CatID SubCatID
------------------------------
1      Task1     0    NULL
2      Task2     1    NULL -- 1 in OP's example
3      Task3     1    2
4      Task4     1    3
5      Task5     2    NULL 
6      Task6     2    5
7      Task7     2    6

我只是将SubCatID设置为版本号的整体从零开始的索引,但在没有“。”的情况下为null。或“小版本”。

我将继续@Lamak的评论,并承认我无法看到Task2和Task5的SubCatID如何都不为空(猜测之外的事情,例如“没有SubCatID for 0所以使下一个CatID非空“)。

要进入OutlineNumber的无限深度,包括可能大于9的节点,解决方案可能采用递归CTE的形式,或者可能是带有动态SQL的proc。