PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Ordinamento alfanumerico con PostgreSQL

Il modo ideale sarebbe normalizzare i tuoi dati e dividi i due componenti della colonna in due colonne singole. Uno di tipo integer , un text .

Con la tabella corrente, puoi fare qualcosa come mostrato qui:

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

Lo stesso substring() le espressioni possono essere utilizzate per dividere la colonna.

Le espressioni regolari sono in qualche modo tolleranti agli errori:

  • La prima regex seleziona la stringa numerica più lunga da sinistra, NULL se non vengono trovate cifre, quindi esegui il cast su integer non puoi sbagliare.

  • La seconda espressione regolare preleva il resto della stringa dal primo carattere che non è una cifra o '_'.

Se il carattere di sottolineatura non è comunque ambiguo come separatore, split_part() è più veloce:

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

Rispondi per il tuo esempio

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