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.) -
\Dje 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
gje 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 naNULLsNULLIF. (Můžete zvážit0mí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.