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