É absolutamente possível.
ORDER BY varchar_column::int
Certifique-se de ter literais inteiros válidos em seu
varchar
coluna para cada entrada ou você obtém uma exceção invalid input syntax for integer: ...
. (O espaço em branco à esquerda e à direita está ok - ele será cortado automaticamente.) Se for esse o caso, por que não converter a coluna para
integer
começar com? Menor, mais rápido, mais limpo, mais simples. Como evitar exceções?
Para remover caracteres que não sejam dígitos antes da conversão e, assim, evitar possíveis exceções:
ORDER BY NULLIF(regexp_replace(varchar_column, '\D', '', 'g'), '')::int
-
Oregexp_replace()
expression remove efetivamente todos os não dígitos, portanto, apenas os dígitos permanecem ou uma string vazia. (Ver abaixo.)
-
\D
é um atalho para a classe de caracteres[^[:digit:]]
, ou seja, todos os não dígitos ([^0-9]
).
Nas versões antigas do Postgres com a configuração desatualizadastandard_conforming_strings = off
, você deve usar a sintaxe de string de escape PosixE'\\D'
para escapar da barra invertida\
. Isso era padrão no Postgres 8.3, então você precisará disso para sua versão desatualizada.
-
O quarto parâmetrog
é para "globalmente" , instruindo a substituir todos ocorrências, não apenas as primeiras.
-
Você pode deseja permitir um traço inicial (-
) para números negativos.
-
Se a string não tiver dígitos, o resultado será uma string vazia que não é válida para uma conversão parainteger
. Converter strings vazias paraNULL
comNULLIF
. (Você pode considerar0
em vez de.)
O resultado é garantido para ser válido. Este procedimento é para uma conversão para
integer
conforme solicitado no corpo da pergunta, não para numeric
como o título menciona. Como fazer isso rápido?
Uma maneira é um índice em uma expressão.
CREATE INDEX tbl_varchar_col2int_idx ON tbl
(cast(NULLIF(regexp_replace(varchar_column, '\D', '', 'g'), '') AS integer));
Em seguida, use a mesma expressão no
ORDER BY
cláusula:ORDER BY
cast(NULLIF(regexp_replace(varchar_column, '\D', '', 'g'), '') AS integer)
Teste com
EXPLAIN ANALYZE
se o índice funcional realmente é usado.