Orden varchar string como numérico


¿Es posible ordenar filas de resultados por una columna varchar convertida a integer en Postgres 8.3?

Author: Erwin Brandstetter, 2011-12-14

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 desactualizada standard_conforming_strings = off, debe usar la sintaxis de cadena de escape Posix E'\\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 a NULL con NULLIF. (Usted podría considerar 0 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.

 83
Author: Erwin Brandstetter,
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;
 0
Author: Eric Leschinski,
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