De ideale manier zou zijn om te normaliseren uw gegevens en splits de twee componenten van de kolom in twee afzonderlijke kolommen. Een van het type integer
, één text
.
Met de huidige tabel kun je zoiets doen als hier gedemonstreerd:
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
Dezelfde substring()
uitdrukkingen kunnen worden gebruikt om de kolom te splitsen.
De reguliere expressies zijn enigszins fouttolerant:
-
De eerste regex kiest de langste numerieke reeks van links,
NULL
als er geen cijfers worden gevonden, dus de cast naarinteger
kan niet fout gaan. -
De tweede regex kiest de rest van de tekenreeks uit het eerste teken dat geen cijfer of '_' is.
Als het onderstrepingsteken toch ondubbelzinnig als scheidingsteken is, split_part()
is sneller:
ORDER BY (split_part(t, '_', 1)::int
,split_part(t, '_', 2)
Antwoord voor uw voorbeeld
SELECT name
FROM nametable
ORDER BY (split_part(name, '_', 1)::int
,split_part(name, '_', 2)