Den ideelle måde ville være at normalisere dine data og opdele kolonnens to komponenter i to individuelle kolonner. En af typen integer
, én text
.
Med den aktuelle tabel kan du gøre noget som vist her:
WITH x(t) AS (
VALUES
('10_asdaasda')
,('100_inkskabsjd')
,('11_kancaascjas')
,('45_aksndsialcn')
,('22_dsdaskjca')
,('100_skdnascbka')
)
SELECT t
FROM x
ORDER BY (substring(t, '^[0-9]+'))::int -- cast to integer
,substring(t, '[^0-9_].*$') -- works as text
Den samme substring()
udtryk kan bruges til at opdele kolonnen.
De regulære udtryk er noget fejltolerante:
-
Det første regex vælger den længste numeriske streng fra venstre,
NULL
hvis der ikke findes nogen cifre, så cast tilinteger
kan ikke gå galt. -
Det andet regex vælger resten af strengen fra det første tegn, der ikke er et ciffer eller '_'.
Hvis understregningen alligevel er utvetydig som separator, split_part()
er hurtigere:
ORDER BY (split_part(t, '_', 1)::int
,split_part(t, '_', 2)
Svar for dit eksempel
SELECT name
FROM nametable
ORDER BY (split_part(name, '_', 1)::int
,split_part(name, '_', 2)