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のコメントを2番目にし、Task2とTask5のSubCatIDが両方ともnullではないことを確認できないことを認めます(「0のSubCatIDがないため、次のCatIDを非nullにする」などの推測を除く) )。

9 を超える可能性のあるノードを含め、OutlineNumber の無限の深さに移動するには、ソリューションは再帰 CTE の形式を取るか、動的 SQL を含む proc を使用する可能性があります。

于 2013-10-10T16:33:45.657 に答える