Cara yang ideal adalah dengan menormalkan data Anda dan pisahkan dua komponen kolom menjadi dua kolom terpisah. Salah satu jenis integer , satu text .
Dengan tabel saat ini, Anda dapat melakukan sesuatu seperti yang ditunjukkan di sini:
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
substring() yang sama ekspresi dapat digunakan untuk memisahkan kolom.
Ekspresi reguler agak toleran terhadap kesalahan:
-
Regex pertama mengambil string numerik terpanjang dari kiri,
NULLjika tidak ada digit yang ditemukan, jadi berikan keintegertidak bisa salah. -
Regex kedua mengambil sisa string dari karakter pertama yang bukan digit atau '_'.
Jika garis bawah tidak ambigu sebagai pemisah, split_part() lebih cepat:
ORDER BY (split_part(t, '_', 1)::int
,split_part(t, '_', 2)
Jawab untuk contoh Anda
SELECT name
FROM nametable
ORDER BY (split_part(name, '_', 1)::int
,split_part(name, '_', 2)