How Can I Sort A 'Version Number' Column Generically Using a SQL Server Query

前端 未结 4 503
天命终不由人
天命终不由人 2020-11-29 08:55

I wonder if the SQL geniuses amongst us could lend me a helping hand.

I have a column VersionNo in a table Versions that contains \'version

相关标签:
4条回答
  • 2020-11-29 09:04

    If You are using SQL Server 2008

    select VersionNo from Versions order by cast('/' + replace(VersionNo , '.', '/') + '/' as hierarchyid);
    

    What is hierarchyid

    Edit:

    Solutions for 2000, 2005, 2008: Solutions to T-SQL Sorting Challenge here.

    The challenge

    0 讨论(0)
  • 2020-11-29 09:13

    Depending on SQL engine for MySQL would be sth like this:

    SELECT versionNo FROM Versions
    ORDER BY
    SUBSTRING_INDEX(versionNo, '.', 1) + 0,
    SUBSTRING_INDEX(SUBSTRING_INDEX(versionNo, '.', -3), '.', 1) + 0,
    SUBSTRING_INDEX(SUBSTRING_INDEX(versionNo, '.', -2), '.', 1) + 0,
    SUBSTRING_INDEX(versionNo, '.', -1) + 0;

    For MySQL version 3.23.15 an above

    SELECT versionNo FROM Versions ORDER BY INET_ATON(ip);
    
    0 讨论(0)
  • 2020-11-29 09:16

    Another way to do it:

    Assuming you only have a,b,c,d only you may as well separate the data out to columns and do an order by a,b,c,d(all desc) and get the top 1 row

    If you need to scale to more than d to say e,f,g... just change 1,2,3,4, to 1,2,3,4,5,6,7 and so on in the query

    Query : see demo

    create table t (versionnumber varchar(255))
    insert into t values
    ('1.0.0.505')
    ,('1.0.0.506')
    ,('1.0.0.507')
    ,('1.0.0.508')
    ,('1.0.0.509')
    ,('1.0.1.2')
    
    
    ; with cte as 
    (
        select 
        column1=row_number() over (order by (select NULL)) ,
        column2=versionnumber
        from t
        )
    
    select top 1
        CONCAT([1],'.',[2],'.',[3],'.',[4])
    from 
    (
        select 
            t.column1,
            split_values=SUBSTRING( t.column2, t1.N, ISNULL(NULLIF(CHARINDEX('.',t.column2,t1.N),0)-t1.N,8000)),
            r= row_number() over( partition by column1 order by t1.N) 
        from cte t 
            join
            (
                select 
                    t.column2,
                    1 as N 
                from cte t  
                    UNION ALL
                select 
                    t.column2,
                    t1.N + 1 as N
                from cte t 
                    join
                    (
                     select 
                        top 8000
                            row_number() over(order by (select NULL)) as N 
                     from 
                        sys.objects s1 
                            cross join 
                       sys.objects s2 
                    ) t1 
                on SUBSTRING(t.column2,t1.N,1) = '.'
             ) t1
              on t1.column2=t.column2
    )a
    pivot
    ( 
        max(split_values) for r in ([1],[2],[3],[4])
       )p
      order by [1] desc,[2] desc,[3] desc,[4] desc
    
    0 讨论(0)
  • 2020-11-29 09:22

    If you can, alter the schema so that the version has 4 columns instead of one. Then sorting is easy.

    0 讨论(0)
提交回复
热议问题