PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Classificação alfanumérica com PostgreSQL


A maneira ideal seria normalizar seus dados e divida os dois componentes da coluna em duas colunas individuais. Um do tipo integer , um text .

Com a tabela atual, você pode fazer algo como demonstrado aqui:
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

A mesma substring() expressões podem ser usadas para dividir a coluna.

As expressões regulares são um pouco tolerantes a falhas:

  • A primeira regex escolhe a string numérica mais longa da esquerda, NULL se nenhum dígito for encontrado, então a conversão para integer não pode dar errado.

  • A segunda regex escolhe o resto da string do primeiro caractere que não é um dígito ou '_'.

Se o sublinhado não for ambíguo como separador, split_part() é mais rápido:
ORDER  BY (split_part(t, '_', 1)::int
          ,split_part(t, '_', 2)

Resposta para o seu exemplo

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