в лоб
WITH test (f ) AS
(values
('S 10')
,('S 140')
,('S 147 A')
,('S 147 C1')
,('S 147 C2')
,('S 147 C10')
,('S 1000')
)
,split (f,arr) AS (SELECT f, regexp_split_to_array(f,E'\\s+') AS arr FROM test)
SELECT f,arr,arr[1] AS "1" ,arr[2]::int AS "2",regexp_replace(arr[3],'\d','','ig') ,(NULLIF(regexp_replace(arr[3],'[[:alpha:]]','','ig'),''))::int
FROM split
ORDER BY 3,4,5,6
или можно сразу регуляризнуть примерно так
WITH test (f ) AS
(values
('S 10')
,('S 140')
,('S 147 A')
,('S 147 C1')
,('S 147 C2')
,('S 147 C10')
,('S 1000')
)
, split AS (SELECT f, regexp_split_to_array(regexp_replace(f,E'([[:alpha:]])(\\d+)','\1 \2','ig' ),E'\\s+') AS arr FROM test)
SELECT * FROM split ORDER BY arr[1],arr[2]::int ,arr[3], arr[4]::int
чтобы особые случаи не рассматривать