Напълно възможно е.
ORDER BY varchar_column::int
Уверете се, че имате валидни целочислени литерали във вашия varchar колона за всеки запис или получавате изключение invalid input syntax for integer: ... . (Началото и крайното бяло пространство е наред – то ще бъде изрязано автоматично.)
Ако случаят е такъв, защо тогава да не конвертирате колоната в integer да започнем с? По-малък, по-бърз, по-чист, по-прост.
Как да избегнем изключения?
За да премахнете нецифрени знаци преди прехвърлянето и по този начин да избегнете възможни изключения:
ORDER BY NULLIF(regexp_replace(varchar_column, '\D', '', 'g'), '')::int
-
regexp_replace()изразът ефективно премахва всички нецифрени числа, така че остават само цифри или празен низ. (Вижте по-долу.) -
\Dе съкращения за класа на знаците[^[:digit:]], което означава всички нецифрени ([^0-9]).
В стари версии на Postgres с остарялата настройкаstandard_conforming_strings = off, трябва да използвате синтаксис на escape низ на PosixE'\\D'за избягване на обратната наклонена черта\. Това беше по подразбиране в Postgres 8.3, така че ще ви трябва за остарялата ви версия. -
Четвъртият параметър
gе за „глобално“ , с инструкция за замяна на всички събития, не само първите. -
Вие можете искате да разрешите водещо тире (
-) за отрицателни числа. -
Ако низът изобщо няма цифри, резултатът е празен низ, който не е валиден за прехвърляне към
integer. Преобразувайте празните низове вNULLсNULLIF. (Можете да помислите за0вместо това.)
Резултатът е гарантирано валиден. Тази процедура е за прехвърляне към integer както е поискано в тялото на въпроса, не за numeric както се споменава в заглавието.
Как да го направя бързо?
Един от начините е индекс на израз.
CREATE INDEX tbl_varchar_col2int_idx ON tbl
(cast(NULLIF(regexp_replace(varchar_column, '\D', '', 'g'), '') AS integer));
След това използвайте същия израз в ORDER BY клауза:
ORDER BY
cast(NULLIF(regexp_replace(varchar_column, '\D', '', 'g'), '') AS integer)
Тествайте с EXPLAIN ANALYZE дали функционалният индекс действително се използва.