Het is absoluut mogelijk.
ORDER BY varchar_column::int
Zorg ervoor dat u geldige letterlijke gehele getallen in uw varchar
heeft kolom voor elke invoer of u krijgt een uitzondering invalid input syntax for integer: ...
. (Voor- en achterliggende witruimte is ok - het wordt automatisch bijgesneden.)
Als dat echter het geval is, waarom converteert u de kolom dan niet naar integer
beginnen met? Kleiner, sneller, schoner, eenvoudiger.
Hoe uitzonderingen vermijden?
Om niet-cijferige tekens voor de cast te verwijderen en zo mogelijke uitzonderingen te voorkomen:
ORDER BY NULLIF(regexp_replace(varchar_column, '\D', '', 'g'), '')::int
-
De
regexp_replace()
expression verwijdert effectief alle niet-cijfers, zodat alleen cijfers of een lege tekenreeks overblijven. (Zie hieronder.) -
\D
is een afkorting voor de tekenklasse[^[:digit:]]
, wat betekent dat alle niet-cijfers ([^0-9]
).
In oude Postgres-versies met de verouderde instellingstandard_conforming_strings = off
, moet u Posix escape string syntaxisE'\\D'
. gebruiken om te ontsnappen aan de backslash\
. Dit was standaard in Postgres 8.3, dus dat heb je nodig voor je verouderde versie. -
De 4e parameter
g
is voor "wereldwijd" , instrueren om alle te vervangen voorvallen, niet alleen de eerste. -
Je mag een voorloopstreepje wilt toestaan (
-
) voor negatieve getallen. -
Als de string helemaal geen cijfers heeft, is het resultaat een lege string die niet geldig is voor een cast naar
integer
. Converteer lege strings naarNULL
metNULLIF
. (Je zou kunnen overwegen0
in plaats daarvan.)
Het resultaat is gegarandeerd geldig. Deze procedure is voor een cast naar integer
zoals gevraagd in de hoofdtekst van de vraag, niet voor numeric
zoals de titel al zegt.
Hoe maak je het snel?
Een manier is een index op een uitdrukking.
CREATE INDEX tbl_varchar_col2int_idx ON tbl
(cast(NULLIF(regexp_replace(varchar_column, '\D', '', 'g'), '') AS integer));
Gebruik dan dezelfde uitdrukking in de ORDER BY
clausule:
ORDER BY
cast(NULLIF(regexp_replace(varchar_column, '\D', '', 'g'), '') AS integer)
Test met EXPLAIN ANALYZE
of de functionele index daadwerkelijk wordt gebruikt.