Sql Server中的版本号排序

pri*_*kar 5 sql t-sql sql-server

我有一个表存储版本

Declare @tblVersion table(VersionNumber varchar(100))
 Insert into @tblVersion Values('1.3.1')
 Insert into @tblVersion Values('1.3.2.5')
 Insert into @tblVersion Values('1.4.1.7.12')
 Insert into @tblVersion Values('1.4.11.14.7')
 Insert into @tblVersion Values('1.4.3.109.1')
 Insert into @tblVersion Values('1.4.8.66')

 Select * From @tblVersion

VersionNumber
1.3.1
1.3.2.5
1.4.1.7.12
1.4.11.14.7
1.4.3.109.1
1.4.8.66
Run Code Online (Sandbox Code Playgroud)

我的要求是我需要对它们进行排序以便输出

VersionNumber
1.3.1
1.3.2.5
1.4.1.7.12
1.4.3.109.1
1.4.8.66
1.4.11.14.7
Run Code Online (Sandbox Code Playgroud)

但是,如果它做一个简单的订单不能按预期工作

Select VersionNumber
 From @tblVersion
 Order By VersionNumber

VersionNumber
1.3.1
1.3.2.5
1.4.1.7.12
1.4.11.14.7
1.4.3.109.1
1.4.8.66
Run Code Online (Sandbox Code Playgroud)

需要帮助

Ste*_*ass 8

如果您使用的是SQL Server 2008或更高版本,则可以使用hierarchyID数据类型:

select * from @tblVersion
order by CAST('/'+REPLACE(VersionNumber,'.','/')+'/' as hierarchyID)
Run Code Online (Sandbox Code Playgroud)

  • 我只是意识到:你不需要用`/`替换`.`,`ORDER BY CAST('/'+ VersionNumber +'/'as hierarchyID)`也可以. (2认同)

Bri*_*ian 5

这通常称为自然排序,在SQL Server中没有简单的方法.通常,数据需要分解为字段或字段的固定长度段.它可以在所需的订单的那些字段上排序.

VersionNumber VersionSort
1.3.1         0001.0003.0001
1.3.2.5       0001.0003.0002.0005
1.4.1.7.12    0001.0004.0001.0007.0012
1.4.11.14.7   0001.0004.0011.0014.0007
1.4.3.109.1   0001.0004.0003.0109.0001
1.4.8.66      0001.0004.0008.0066
Run Code Online (Sandbox Code Playgroud)


pri*_*kar 1

Brain解决方案的实施

Declare @tblVersion table(VersionNumber varchar(100)) 
 Insert into @tblVersion Values('1.3.1') 
 Insert into @tblVersion Values('1.3.2.5') 
 Insert into @tblVersion Values('1.4.1.7.12') 
 Insert into @tblVersion Values('1.4.11.14.7') 
 Insert into @tblVersion Values('1.4.3.109.1') 
 Insert into @tblVersion Values('1.4.8.66') 

 --Select * From @tblVersion 

 ;With CTE AS
 (
    Select 
        Rn = Row_Number() Over(Order By (Select 1))
        ,VersionNumber
    From @tblVersion
)
,CTESplit AS
(
    SELECT 
            F1.Rn,
            F1.VersionNumber,
            VersionSort = 
                            Case 
                                    When Len(O.VersionSort) = 1 Then '000' + O.VersionSort
                                    When Len(O.VersionSort) = 2 Then '00' + O.VersionSort
                                    When Len(O.VersionSort) = 3 Then '0' + O.VersionSort
                                    When Len(O.VersionSort) = 4 Then O.VersionSort
                            End

    FROM
    (
        SELECT *,
        cast('<X>'+replace(F.VersionNumber,'.','</X><X>')+'</X>' as XML) as xmlfilter from CTE F
    )F1
 CROSS APPLY
 ( 
    SELECT fdata.D.value('.','varchar(50)') as VersionSort  
    FROM f1.xmlfilter.nodes('X') as fdata(D)) O
 )
 ,CTE3 As(
Select 
        --Rn 
        --,
        VersionNumber
        ,SortableVersion = 
                            Stuff(
                                    (Select '.' + Cast(VersionSort As Varchar(100))
                             From CTESplit c2
                             Where c2.Rn = c1.Rn
                             For Xml Path('')),1,1,'')
From CTESplit c1
Group By c1.Rn,c1.VersionNumber
)
Select VersionNumber
From CTE3
Order By SortableVersion
Run Code Online (Sandbox Code Playgroud)