1

我有一列数字存储为用句点分隔的字符 - 用作父子分组机制。由于 varchar 的性质和 100 在 11 之前出现排序问题,如下面的粗体突出显示:

01
01.01
01.02
01.03
01.03.01
01.03.02
...
01.03.10
01.03.100
01.03.101
01.03.11
01.03.12
...
01.04
01.04.01
01.04.01.01
01.04.01.02
01.04.01.03
01.04.02
01.04.03
02
02.01

ETC

关于如何以数字方式订购这些字符的任何想法?可能有无限的子节点,所以这不是不可能的:

nn.nn.nn.nn.nn.nn.nn.nn.nn.nn 等

谢谢!

4

1 回答 1

3

如果树的深度1有限制,那么您可以编写如下内容:

declare @t table (OrdCol varchar(50) not null)
insert into @t (OrdCol) values
('01'),
('01.01'),
('01.02'),
('01.03'),
('01.03.01'),
('01.03.02'),
('01.03.10'),
('01.03.100'),
('01.03.101'),
('01.03.11'),
('01.03.12'),
('01.04'),
('01.04.01'),
('01.04.01.01'),
('01.04.01.02'),
('01.04.01.03'),
('01.04.02'),
('01.04.03'),
('02'),
('02.01')

select OrdCol from
(select OrdCol,CAST('<a><b>' + REPLACE(OrdCol,'.','</b><b>') + '</b></a>' as xml) as xOrd from @t
) t
order by
    xOrd.value('(a/b)[1]','int'),
    xOrd.value('(a/b)[2]','int'),
    xOrd.value('(a/b)[3]','int'),
    xOrd.value('(a/b)[4]','int'),
    xOrd.value('(a/b)[5]','int'),
    xOrd.value('(a/b)[6]','int'),
    xOrd.value('(a/b)[7]','int'),
    xOrd.value('(a/b)[8]','int'),
    xOrd.value('(a/b)[9]','int'),
    xOrd.value('(a/b)[10]','int')

1为什么我对您关于“无限”儿童的解释方式的问题提出澄清评论。此查询在每个级别处理无限数量的子级,但仅处理最多 10 个深度。


无限深度版本,只要0在任何数字上最多有一个前导即可工作:

select OrdCol from
(select OrdCol,CAST(REPLACE(REPLACE('.' + OrdCol + '.','.0','.'),'.','/') as hierarchyid) as hOrd from @t
) t
order by
    hOrd

它只是对字符串进行处理,直到它符合可转换为的格式hierarchyid,该格式已经按照您期望的顺序执行排序。当然,如果这是有效的,您可能会考虑更改列数据类型以使用此类型。

于 2013-07-25T06:41:26.483 回答