Oracle SQL to Sort Version Numbers

后端 未结 3 1096
有刺的猬
有刺的猬 2021-01-03 09:06

In Oracle, just using the ORDER BY does not sort version numbers. My Version_Number field is declared as a VARCHAR and I cannot change

相关标签:
3条回答
  • 2021-01-03 09:35

    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
    
    0 讨论(0)
  • 2021-01-03 09:43

    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)
    
    0 讨论(0)
  • 2021-01-03 09:55

    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
    
    0 讨论(0)
提交回复
热议问题