Oracle SQL to Sort Version Numbers

时光总嘲笑我的痴心妄想 提交于 2019-11-30 15:57:11

This is one way to do it. First order by the number before . and then by the numbers after .

select version_number 
from mytable 
order by substr(version_number, 1, instr(version_number,'.')-1) desc
        ,length(substr(version_number, instr(version_number,'.')+1)) desc
        ,substr(version_number, instr(version_number,'.')+1) desc

This SQL supports your input data plus any included Revision or Build digits.

with 
   inputs as (select '1.20'         as version_number from dual union all  
              select '1.9'          as version_number from dual union all
              select '1.18'         as version_number from dual union all
              select '1.13'         as version_number from dual union all
              select '1.5'          as version_number from dual union all
              select '1.11'         as version_number from dual union all
              select '2.0'          as version_number from dual union all
              select '1.8'          as version_number from dual union all
              select '1.3'          as version_number from dual union all
              select '1.2'          as version_number from dual union all
              select '1.1'          as version_number from dual union all
              select '1.0'          as version_number from dual union all
              select '1.10'         as version_number from dual union all
              select ' 3.1 '        as version_number from dual union all
              select '3.1.1000'     as version_number from dual union all
              select '3.1.1'        as version_number from dual union all
              select '3.1.100'      as version_number from dual union all
              select '3.1.2.1000'   as version_number from dual union all
              select '3.1.2.1'      as version_number from dual union all
              select '3.1.2.100 '   as version_number from dual)
,versions as  (select  trim(version_number) as version_number,
        nvl(LPAD(trim(regexp_substr(version_number, '[^.]+', 1, 1)),5,'0'),'00000') AS Major,
        nvl(LPAD(trim(regexp_substr(version_number, '[^.]+', 1, 2)),5,'0'),'00000') AS Minor, 
        nvl(LPAD(trim(regexp_substr(version_number, '[^.]+', 1, 3)),5,'0'),'00000') AS Revision, 
        nvl(LPAD(trim(regexp_substr(version_number, '[^.]+', 1, 4)),5,'0'),'00000') AS Build 
        from inputs 
        ORDER BY Major desc, Minor desc, Revision desc, Build desc)
--select * from versions; 
select version_number from versions; 

Remove the -- to see the intermediate result.

For OP, replace "inputs as (select ... from dual)" with:

   inputs as (select version_number from mytable)
S3DEV

As Joel Coehoorn suggestions here, "refactor version number storage so that each section has it's own column: MajorVersion, MinorVersion, Revision, Build".

I'm re-posting as I found this very helpful!

To expand, I was looking to get the MAX version number, and ended up using this script along with Joel's suggestion.

    -- GET MAX VERSION NUMBER
    SELECT
        REPLACE(vnum, ' ', '') AS versionum
    FROM
        (SELECT
            MAX(LPAD(major, 4) || '.' || LPAD(minor, 4) || '.' || LPAD(revision, 4)) AS vnum
        FROM
            my_table
        ORDER BY
            major
          , minor
          , revision
        ) tbl1
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!