Der ideale Weg wäre die Normalisierung Ihre Daten und teilen Sie die beiden Komponenten der Spalte in zwei einzelne Spalten auf. Einer vom Typ integer
, ein text
.
Mit der aktuellen Tabelle können Sie etwas wie hier gezeigt machen:
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
Derselbe substring()
Ausdrücke können verwendet werden, um die Spalte zu teilen.
Die regulären Ausdrücke sind einigermaßen fehlertolerant:
-
Die erste Regex wählt die längste numerische Zeichenfolge von links,
NULL
wenn keine Ziffern gefunden werden, erfolgt die Umwandlung ininteger
kann nichts schief gehen. -
Die zweite Regex wählt den Rest der Zeichenfolge aus dem ersten Zeichen aus, das keine Ziffer oder '_' ist.
Wenn der Unterstrich als Trennzeichen ohnehin eindeutig ist, split_part()
ist schneller:
ORDER BY (split_part(t, '_', 1)::int
,split_part(t, '_', 2)
Antwort für dein Beispiel
SELECT name
FROM nametable
ORDER BY (split_part(name, '_', 1)::int
,split_part(name, '_', 2)