1

有 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

4

1 回答 1

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 是如何不为空的(除了猜测诸如“0 没有 SubCatID 所以使下一个 CatID 非空”之类的事情之外)。

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

于 2013-10-10T16:33:45.657 回答