Вот один из способов сделать это.Предполагая, что все входные данные имеют одну или несколько цифр, за которыми следует точка, за которой следуют одна или несколько цифр, за которыми следует некоторый другой фрагмент (возможно, пустой), который не начинается с цифры ... Порядок по убыванию первого целого числа, затемвторое целое число по убыванию, затем по оставшемуся фрагменту ASCENDING и с нулевыми первыми (так, например, прошивка '3.8' предшествует '3.8A'):
with
inputs (firmware) as (
select '3.9P7S1' from dual union all
select '3.10P4S1' from dual union all
select '3.9PX20K' from dual union all
select '3.1ST8X2' from dual union all
select '3.1' from dual union all
select '2.9P7S1' from dual union all
select '3.9ABC32' from dual
)
select firmware
from inputs
order by to_number(regexp_substr(firmware, '^\d+')) desc,
to_number(regexp_substr(firmware, '^\d+\.(\d+)', 1, 1, null, 1)) desc,
regexp_replace(firmware, '\d+\.\d+') asc nulls first
;
FIRMWARE
--------
3.10P4S1
3.9ABC32
3.9P7S1
3.9PX20K
3.1
3.1ST8X2
2.9P7S1