【问题标题】:Outline Number Column to Parent and Child大纲编号列给父母和孩子
【发布时间】:2013-10-10 14:56:52
【问题描述】:

具有大纲编号为的数据库表:

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

【问题讨论】:

  • outlinenumber 可以嵌套多远? 2.1.1 是最长的字符串,还是 2.1.1.1.1.1?
  • 这种嵌套方法效率不高。试着看看这个:slideshare.net/billkarwin/models-for-hierarchical-data(后半部分,闭表)
  • 那么,为什么Task2SubCatID 等于1 而Task5 没有SubCatID 等于2?
  • SubCatID 来自哪里?由于值没有出现在您的源数据中?它是某种形式的增量数字(计算空值)吗?!
  • @Tanner,在我看来,它应该是来自“父”任务的PID。我的理论的问题是PID = 2PID = 1 作为父级,但PID = 5 没有PID = 2 作为父级。似乎不一致

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


【解决方案1】:

由于我们还不知道 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。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-22
    • 2012-08-29
    • 2014-05-19
    • 1970-01-01
    • 2012-09-28
    • 2011-08-29
    相关资源
    最近更新 更多