Idealnym sposobem byłaby normalizacja swoje dane i podziel dwa składniki kolumny na dwie oddzielne kolumny. Jeden z typów integer
, jeden text
.
Przy obecnej tabeli możesz zrobić coś takiego, jak zademonstrowano tutaj:
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
Ten sam substring()
do podziału kolumny można użyć wyrażeń.
Wyrażenia regularne są w pewnym stopniu odporne na błędy:
-
Pierwsze wyrażenie regularne wybiera najdłuższy ciąg liczbowy od lewej,
NULL
jeśli nie zostaną znalezione żadne cyfry, rzutuj nainteger
nie może się nie udać. -
Drugie wyrażenie regularne wybiera resztę ciągu z pierwszego znaku, który nie jest cyfrą ani „_”.
Jeśli podkreślenie i tak jest jednoznaczne jako separator, split_part()
jest szybszy:
ORDER BY (split_part(t, '_', 1)::int
,split_part(t, '_', 2)
Odpowiedz na swój przykład
SELECT name
FROM nametable
ORDER BY (split_part(name, '_', 1)::int
,split_part(name, '_', 2)