Orden varchar string como numérico
¿Es posible ordenar filas de resultados por una columna varchar
convertida a integer
en Postgres 8.3?
2 answers
Es absolutamente posible.
ORDER BY varchar_column::int
Asegúrese de tener literales enteros válidos en su columna varchar
o obtendrá una excepción. (El espacio en blanco inicial y final está bien , se recortará automáticamente.)
Si ese es el caso, entonces ¿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 excepciones?
Para eliminar los caracteres que no son dígitos antes del molde y así evitar posibles excepciones:
ORDER BY NULLIF(regexp_replace(varchar_column, '\D', '', 'g'), '')::int
Las
regexp_replace()
expression elimina efectivamente todos los que no son dígitos, por lo que solo quedan dígitos o una cadena vacía. (Véase más adelante.)\D
es una abreviatura de la clase de caracteres[^[:digit:]]
, que significa todos los no dígitos ([^0-9]
).
En versiones antiguas de Postgres con la configuración desactualizadastandard_conforming_strings = off
, debe usar la sintaxis de cadena de escape PosixE'\\D'
para escapar de la barra invertida\
. Esto fue predeterminado en Postgres 8.3, por lo que lo necesitará para su obsoleto versión.El 4to parámetro
g
es para "globalmente", instruyendo para reemplazar todas las ocurrencias, no solo la primera.puede que quiera permitir un guión inicial (
-
) para números negativos.Si la cadena the no tiene dígitos, el resultado es una cadena vacía que no es válida para un cast a
integer
. Convertir cadenas vacías aNULL
conNULLIF
. (Usted podría considerar0
en su lugar.)
El resultado está garantizado para ser válido. Este procedimiento es para un yeso para integer
como se pide en el cuerpo de la pregunta, no para numeric
como menciona el título.
¿Cómo hacerlo rápido?
Una forma es un índice en una expresión. (Enlace a la versión manual 8.3.)
CREATE INDEX tbl_varchar_col2int_idx ON tbl
(cast(NULLIF(regexp_replace(varchar_column, E'\\D', '', 'g'), '') AS integer));
Luego use la misma expresión en la cláusula ORDER BY
:
ORDER BY
cast(NULLIF(regexp_replace(varchar_column, E'\\D', '', 'g'), '') AS integer)
Prueba con EXPLAIN ANALYZE
si el índice funcional realmente se acostumbra.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-20 01:31:23
También en caso de que desee ordenar por una columna de texto que tiene algo convertible para flotar, entonces esto lo hace:
select *
from your_table
order by cast(your_text_column as double precision) desc;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-04 02:34:41