Det er absolut muligt.
ORDER BY varchar_column::int
Sørg for at have gyldige heltalsliteraler i din varchar kolonne for hver post, eller du får en undtagelse invalid input syntax for integer: ... . (Første og efterfølgende hvide mellemrum er ok - det trimmes automatisk.)
Hvis det er tilfældet, hvorfor så ikke konvertere kolonnen til integer til at starte med? Mindre, hurtigere, renere, enklere.
Hvordan undgår man undtagelser?
For at fjerne ikke-cifrede tegn før rollebesætningen og derved undgå mulige undtagelser:
ORDER BY NULLIF(regexp_replace(varchar_column, '\D', '', 'g'), '')::int
-
regexp_replace()udtryk fjerner effektivt alle ikke-cifre, så kun cifre er tilbage eller en tom streng. (Se nedenfor.) -
\Der en forkortelse for tegnklassen[^[:digit:]], hvilket betyder alle ikke-cifre ([^0-9]).
I gamle Postgres-versioner med den forældede indstillingstandard_conforming_strings = off, skal du bruge Posix escape streng syntaksE'\\D'for at undslippe omvendt skråstreg\. Dette var standard i Postgres 8.3, så det skal du bruge til din forældede version. -
Den 4. parameter
ger for "globalt" , med instruktion om at erstatte alle hændelser, ikke kun den første. -
Du må ønsker at tillade en indledende bindestreg (
-) for negative tal. -
Hvis strengen slet ikke har nogen cifre, er resultatet en tom streng, som ikke er gyldig for en cast til
integer. Konverter tomme strenge tilNULLmedNULLIF. (Du kan overveje0i stedet.)
Resultatet er garanteret gyldigt. Denne procedure er for en cast til integer som anmodet i brødteksten i spørgsmålet, ikke for numeric som titlen nævner.
Hvordan gør man det hurtigt?
En måde er et indeks på et udtryk.
CREATE INDEX tbl_varchar_col2int_idx ON tbl
(cast(NULLIF(regexp_replace(varchar_column, '\D', '', 'g'), '') AS integer));
Brug derefter det samme udtryk i ORDER BY klausul:
ORDER BY
cast(NULLIF(regexp_replace(varchar_column, '\D', '', 'g'), '') AS integer)
Test med EXPLAIN ANALYZE om funktionsindekset rent faktisk bliver brugt.