This should do it:
order by regexp_replace(the_column, '[^0-9\.]', '', 'g')::numeric DESC
It removes all character that are non-numeric (leaves only digits and the .) from the value and then converts it into a number. That number is then used to sort descending
The only thing is that 5.0 will be sorted after 5.1 with the above.
If you need to take values into account which don't have any digits, something like this:
order by
case
when regexp_replace(the_column, '[^0-9\.]', '', 'g') <>
then regexp_replace(the_column, '[^0-9\.]', '', 'g')::numeric
end DESC NULLS LAST,
the_column DESC -- to sort the "NULL" values alphabetically
If you don't want to repeat the regex expression you could do something like this:
with clean_data as (
select the_column,
regexp_replace(the_column, '[^0-9\.]', '', 'g') as clean_column,
....
from ...
)
select *
from clean_data
order by case
when clean_column <> '' then clean_column::numeric
end desc nulls last,
the_column desc;