PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Tri alphanumérique avec PostgreSQL

L'idéal serait de normaliser vos données et divisez les deux composants de la colonne en deux colonnes individuelles. Un de type integer , un text .

Avec le tableau actuel, vous pouvez faire quelque chose comme démontré ici :

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

Le même substring() des expressions peuvent être utilisées pour diviser la colonne.

Les expressions régulières sont quelque peu tolérantes aux pannes :

  • La première regex sélectionne la chaîne numérique la plus longue à partir de la gauche, NULL si aucun chiffre n'est trouvé, donc le cast en integer ne peut pas se tromper.

  • La deuxième regex sélectionne le reste de la chaîne à partir du premier caractère qui n'est pas un chiffre ou '_'.

Si le trait de soulignement est de toute façon sans ambiguïté comme séparateur, split_part() est plus rapide :

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

Répondez à votre exemple

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