Я обсуждал это на другом форуме, где мы придумали XML-решение, которое было очень динамичным. Адам Хейнс помог оптимизировать его, что значительно улучшило производительность. Эта версия содержит исправление для правильной сортировки букв алфавита.
Учитывая следующие значения:
declare @temp table (id varchar(255))
insert into @temp (id) values
('1.1.a.1'),('1.1.aa.2'),
('1.1.b.3'),('1.1.a.4'),
('1.1.a.5'),('1.1.a.6'),
('1.1.a.7'),('1.1.a.8'),
('1.1.a.9'),('1.1.a.10'),
('1.1.a.11'),('1.1.b.1'),
('1.1.b.2'),('1.2.a.1'),
('1.10.a.1'),('1.11.a.1'),
('1.20.a.1'),('101.20.a.2'),
('1.20.a.150'),('1.1'),
('1.2'),('1')
Этот запрос:
declare @xml xml,
@max_len int
set @xml =
(
select id as id, cast('<i>' + replace(id,'.','</i><i>') + '</i>' as xml)
from @temp
for xml path('id_root'),type
)
select @max_len = max(len(x.i.value('.','varchar(10)')))
from @xml.nodes('/id_root/i') x(i)
select [id]--, srt.srtvalue
from @temp
cross apply(
select case when ISNUMERIC(x.i.value('.','varchar(10)')) = 1 then right(replicate('0',@max_len) + x.i.value('.','varchar(10)'),@max_len) else x.i.value('.','varchar(10)') end + '.'
from @xml.nodes('/id_root/i') x(i)
where x.i.value('../id[1]','varchar(50)') = [@temp].id
for xml path('')
) as srt(srtvalue)
order by srt.srtvalue
Возвращает эти значения:
id
1
1.1
1.1.a.1
1.1.a.4
1.1.a.5
1.1.a.6
1.1.a.7
1.1.a.8
1.1.a.9
1.1.a.10
1.1.a.11
1.1.aa.2
1.1.b.1
1.1.b.2
1.1.b.3
1.2
1.2.a.1
1.10.a.1
1.11.a.1
1.20.a.1
1.20.a.150
101.20.a.2
Если у вас более 10 символов в одной цифре, вам придется соответствующим образом изменить varchar (10).
- Джеймс