sql >> Base de Datos >  >> RDS >> PostgreSQL

Clasificación alfanumérica con PostgreSQL

La forma ideal sería normalizar sus datos y divida los dos componentes de la columna en dos columnas individuales. Uno de tipo integer , un text .

Con la tabla actual, puede hacer algo como lo que se muestra aquí:

WITH x(t) AS (
    VALUES
     ('10_asdaasda')
    ,('100_inkskabsjd')
    ,('11_kancaascjas')
    ,('45_aksndsialcn')
    ,('22_dsdaskjca')
    ,('100_skdnascbka')
    )
SELECT t
FROM   x
ORDER  BY (substring(t, '^[0-9]+'))::int     -- cast to integer
          ,substring(t, '[^0-9_].*$')        -- works as text

La misma substring() se pueden usar expresiones para dividir la columna.

Las expresiones regulares son algo tolerantes a fallas:

  • La primera expresión regular elige la cadena numérica más larga de la izquierda, NULL si no se encuentran dígitos, entonces la conversión a integer no puede salir mal.

  • La segunda expresión regular elige el resto de la cadena del primer carácter que no es un dígito o '_'.

Si el guión bajo no es ambiguo como separador de todos modos, split_part() es más rápido:

ORDER  BY (split_part(t, '_', 1)::int
          ,split_part(t, '_', 2)

Respuesta para tu ejemplo

SELECT name
FROM   nametable
ORDER  BY (split_part(name, '_', 1)::int
          ,split_part(name, '_', 2)