Je to naprosto možné.
ORDER BY varchar_column::int
Ujistěte se, že máte v varchar
platné celočíselné literály sloupec pro každý záznam nebo získáte výjimku invalid input syntax for integer: ...
. (Začátek a konec prázdného místa je v pořádku – bude automaticky oříznut.)
Pokud je to však tento případ, proč nepřevést sloupec na integer
začít s? Menší, rychlejší, čistší, jednodušší.
Jak se vyhnout výjimkám?
Chcete-li před přetypováním odstranit nečíselné znaky a vyhnout se tak možným výjimkám:
ORDER BY NULLIF(regexp_replace(varchar_column, '\D', '', 'g'), '')::int
-
regexp_replace()
výraz účinně odstraní všechny nečíslice, takže zůstanou pouze číslice nebo prázdný řetězec. (Viz níže.) -
\D
je zkratka pro třídu znaků[^[:digit:]]
, což znamená všechny nečíslice ([^0-9]
).
Ve starých verzích Postgresu se zastaralým nastavenímstandard_conforming_strings = off
, musíte použít syntaxi escape řetězce PosixE'\\D'
pro opuštění zpětného lomítka\
. Toto bylo výchozí v Postgres 8.3, takže to budete potřebovat pro svou zastaralou verzi. -
4. parametr
g
je pro "globálně" , pokyn k nahrazení všech výskyty, nejen první. -
můžete chcete povolit úvodní pomlčku (
-
) pro záporná čísla. -
Pokud řetězec neobsahuje vůbec žádné číslice, výsledkem je prázdný řetězec, který není platný pro přetypování na
integer
. Převeďte prázdné řetězce naNULL
sNULLIF
. (Můžete zvážit0
místo toho.)
Výsledek je zaručeně platný. Tento postup je pro přetypování na integer
jak je požadováno v těle otázky, nikoli pro numeric
jak název zmiňuje.
Jak to udělat rychle?
Jedním ze způsobů je index na výrazu.
CREATE INDEX tbl_varchar_col2int_idx ON tbl
(cast(NULLIF(regexp_replace(varchar_column, '\D', '', 'g'), '') AS integer));
Poté použijte stejný výraz v ORDER BY
klauzule:
ORDER BY
cast(NULLIF(regexp_replace(varchar_column, '\D', '', 'g'), '') AS integer)
Otestujte pomocí EXPLAIN ANALYZE
zda se funkční index skutečně využije.