Ideálním způsobem by byla normalizace vaše data a rozdělte dvě součásti sloupce do dvou samostatných sloupců. Jeden z typu integer
, jeden text
.
S aktuální tabulkou můžete udělat něco, co je ukázáno zde:
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
Stejný substring()
výrazy lze použít k rozdělení sloupce.
Regulární výrazy jsou poněkud odolné proti chybám:
-
První regulární výraz vybere nejdelší číselný řetězec zleva,
NULL
pokud nejsou nalezeny žádné číslice, přetypuje se nainteger
nemůže se to pokazit. -
Druhý regulární výraz vybere zbytek řetězce z prvního znaku, který není číslicí nebo '_'.
Pokud je podtržítko jednoznačné jako oddělovač, split_part()
je rychlejší:
ORDER BY (split_part(t, '_', 1)::int
,split_part(t, '_', 2)
Odpověď na váš příklad
SELECT name
FROM nametable
ORDER BY (split_part(name, '_', 1)::int
,split_part(name, '_', 2)