如何通过multipart X.Y [.Z]“version”数字来订购查询结果?

时间:2015-02-05 15:38:04

标签: sql sql-server sql-server-2008 tsql

我有这些数据:

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));

我试图粘贴一些零和顺序,但显然我还没有得到它。

4 个答案:

答案 0 :(得分:2)

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

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

这个想法是按长度排序,因为最后的较小数字的长度较短 - 给定值的存储方式。

这可以修改为更一般,具体取决于您的数据真实情况。

答案 1 :(得分:2)

怎么样:

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

借用内森贝德福德'{3}}中的'劫持'PARSENAME功能

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

答案 2 :(得分:1)

这适用于任何包含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)

看起来有点乱,但是:)

答案 3 :(得分:0)

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

    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