Sangat mungkin.
ORDER BY varchar_column::int
Pastikan untuk memiliki literal integer yang valid di varchar
kolom untuk setiap entri atau Anda mendapatkan pengecualian invalid input syntax for integer: ...
. (Spasi putih di depan dan di belakang tidak masalah - spasi akan dipangkas secara otomatis.)
Namun, jika itu masalahnya, mengapa tidak mengonversi kolom menjadi integer
memulai dengan? Lebih kecil, lebih cepat, lebih bersih, lebih sederhana.
Bagaimana cara menghindari pengecualian?
Untuk menghapus karakter non-digit sebelum pemeran dan dengan demikian menghindari kemungkinan pengecualian:
ORDER BY NULLIF(regexp_replace(varchar_column, '\D', '', 'g'), '')::int
-
regexp_replace()
ekspresi secara efektif menghapus semua non-digit, jadi hanya digit yang tersisa atau string kosong. (Lihat di bawah.) -
\D
adalah singkatan untuk kelas karakter[^[:digit:]]
, artinya semua non-digit ([^0-9]
).
Dalam versi Postgres lama dengan pengaturan lamastandard_conforming_strings = off
, Anda harus menggunakan sintaks string escape PosixE'\\D'
untuk menghindari garis miring terbalik\
. Ini adalah default di Postgres 8.3, jadi Anda memerlukannya untuk versi lama Anda. -
Parameter ke-4
g
adalah untuk "secara global" , menginstruksikan untuk mengganti semua kejadian, bukan hanya yang pertama. -
Anda mungkin ingin mengizinkan tanda hubung awal (
-
) untuk bilangan negatif. -
Jika string tidak memiliki digit sama sekali, hasilnya adalah string kosong yang tidak valid untuk dilemparkan ke
integer
. Ubah string kosong menjadiNULL
denganNULLIF
. (Anda dapat mempertimbangkan0
sebagai gantinya.)
Hasilnya dijamin valid. Prosedur ini untuk cast ke integer
seperti yang diminta di badan pertanyaan, bukan untuk numeric
seperti judulnya.
Bagaimana membuatnya cepat?
Salah satu caranya adalah dengan mengindeks ekspresi.
CREATE INDEX tbl_varchar_col2int_idx ON tbl
(cast(NULLIF(regexp_replace(varchar_column, '\D', '', 'g'), '') AS integer));
Kemudian gunakan ekspresi yang sama di ORDER BY
klausa:
ORDER BY
cast(NULLIF(regexp_replace(varchar_column, '\D', '', 'g'), '') AS integer)
Uji dengan EXPLAIN ANALYZE
apakah indeks fungsional benar-benar digunakan.