如何按 multipart X.Y[.Z] "version" 数字对查询结果进行排序?

How to order query result by multipart X.Y[.Z] "version" numbers?

我有这个数据:

nov_id
2.1.1 
2.1.10
2.1.11
2.1.12
2.1.13
2.1.14
2.1.2 
2.1.3 
2.1.4 
2.1.5 
2.1.6 
2.1.7 
2.1.8 
2.1.9 
2.2   
2.3   
2.4   
2.5   
2.6   

我需要订购我的结果,所以我的预期结果是这样的:

nov_id
2.1.1 
2.1.2 
2.1.3 
2.1.4 
2.1.5 
2.1.6 
2.1.7 
2.1.8 
2.1.9 
2.1.10
2.1.11
2.1.12
2.1.13
2.1.14
2.2   
2.3   
2.4   
2.5   
2.6   

这是我的尝试之一:

Select nov_id 
From dbo.NS_tbl_sc_novedad
Order by Convert(int,Left(Ltrim(Rtrim(replace(nov_id,'.','')))+'0000',4));

我试图粘贴一些零并以此为序,但显然我还没有明白。

对于您的特定数据,这将有效:

order by left(mov_id, 3),
         len(mov_id),
         mov_id

我们的想法是按长度排序,因为末尾较小的数字长度较短 -- 给定值的存储方式。

这可以修改为更通用,具体取决于您的数据的实际情况。

这是我的(可能设计过度的解决方案)...但它有效

    declare @temp table (value varchar(20),orderby int)

insert into @temp (value)
Values( '2.1.1'),
('2.1.10'),
('2.1.11'),
('2.1.12'),
('2.1.13'),
('2.1.14'),
('2.1.2'),
('2.1.3'), 
('2.1.4'),
('2.1.5'),
('2.1.6'),
('2.1.7'),
('2.1.8'),
('2.1.9'),
('2.2'),   
('2.3'),   
('2.4'),   
('2.5'),   
('2.6') 

UPdate @temp set orderby= case when len(replace(value,'.',''))=2 then replace(value,'.','')*100
                               when len(replace(value,'.',''))=3 then replace(value,'.','')*10
                               else replace(value,'.','') end
SELECT value FROM @temp
order by orderby ASC

以上给出了结果集

2.1.1
2.1.10
2.1.11
2.1.12
2.1.13
2.1.14
2.1.2
2.1.3
2.1.4
2.1.5
2.1.6
2.1.7
2.1.8
2.1.9
2.2
2.3
2.4
2.5
2.6

这应该适用于任何包含 2 或 3 个部分且数字中包含任意数字的字符串,例如 1546.345.245 和 999.34

select
  nov_id
from data
cross apply (
  select charindex('.', nov_id) as pos
) as c1
cross apply (
   select charindex('.', nov_id, c1.pos+1) as pos
) as c2
order by
  convert(int, left(nov_id, c1.pos-1)),
  convert(int, substring(nov_id, c1.pos+1, isnull(nullif(c2.pos, 0), 100)-c1.pos-1)),
  convert(int, case c2.pos when 0 then 0 else substring(nov_id, c2.pos+1, 100) end)

不过看起来有点乱:)

怎么样:

SELECT nov_id
FROM @example
ORDER BY 
  CASE WHEN PARSENAME(nov_id, 3) IS NULL THEN 
    CAST(PARSENAME(nov_id, 2) AS INTEGER)*10000
    +CAST(PARSENAME(nov_id, 1) AS INTEGER)*100
  ELSE 
    CAST(PARSENAME(nov_id, 3) AS INTEGER)*10000
    +CAST(PARSENAME(nov_id, 2) AS INTEGER)*100
    +CAST(PARSENAME(nov_id, 1) AS INTEGER)
  END

借鉴 Nathan Bedford 的 'hijacking' How do I split a string so I can access item x?

中的 PARSENAME 函数

它适用于 99.99.99 以内的号码。要支持更多数字,您需要增加 CASE 语句中的倍数。