Es absolutamente posible.
ORDER BY varchar_column::int
Asegúrese de tener literales enteros válidos en su varchar
columna para cada entrada o obtiene una excepción invalid input syntax for integer: ...
. (Los espacios en blanco iniciales y finales están bien; se recortarán automáticamente).
Sin embargo, si ese es el caso, ¿por qué no convertir la columna a integer
? ¿para empezar? Más pequeño, más rápido, más limpio, más simple.
¿Cómo evitar las excepciones?
Para eliminar caracteres que no sean dígitos antes de la conversión y así evitar posibles excepciones:
ORDER BY NULLIF(regexp_replace(varchar_column, '\D', '', 'g'), '')::int
-
El
regexp_replace()
expresión elimina efectivamente todos los que no son dígitos, por lo que solo quedan dígitos o una cadena vacía. (Ver más abajo). -
\D
es la abreviatura de la clase de carácter[^[:digit:]]
, es decir, todos los que no sean dígitos ([^0-9]
).
En versiones antiguas de Postgres con la configuración obsoletastandard_conforming_strings = off
, debe usar la sintaxis de cadena de escape de PosixE'\\D'
para escapar de la barra invertida\
. Esto era predeterminado en Postgres 8.3, por lo que lo necesitará para su versión obsoleta. -
El cuarto parámetro
g
es para "globalmente" , indicando que se reemplacen todos ocurrencias, no solo las primeras. -
Usted puede desea permitir un guión inicial (
-
) para números negativos. -
Si la cadena no tiene ningún dígito, el resultado es una cadena vacía que no es válida para una conversión a
integer
. Convierte cadenas vacías aNULL
conNULLIF
. (Puede considerar0
en su lugar.)
Se garantiza que el resultado es válido. Este procedimiento es para una conversión a integer
como se solicita en el cuerpo de la pregunta, no para numeric
como lo menciona el título.
¿Cómo hacerlo rápido?
Una forma es un índice en una expresión.
CREATE INDEX tbl_varchar_col2int_idx ON tbl
(cast(NULLIF(regexp_replace(varchar_column, '\D', '', 'g'), '') AS integer));
Luego usa la misma expresión en el ORDER BY
cláusula:
ORDER BY
cast(NULLIF(regexp_replace(varchar_column, '\D', '', 'g'), '') AS integer)
Prueba con EXPLAIN ANALYZE
si el índice funcional realmente se usa.