sql >> Databasteknik >  >> RDS >> PostgreSQL

Alfanumerisk sortering med PostgreSQL

Det ideala sättet skulle vara att normalisera dina data och dela upp de två komponenterna i kolumnen i två individuella kolumner. En av typen integer , en text .

Med den aktuella tabellen kan du göra något som visas här:

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

Samma substring() uttryck kan användas för att dela kolumnen.

De reguljära uttrycken är något feltoleranta:

  • Det första regexet väljer den längsta numeriska strängen från vänster, NULL om inga siffror hittas, så cast till integer kan inte gå fel.

  • Det andra regexet väljer resten av strängen från det första tecknet som inte är en siffra eller '_'.

Om understrecket ändå är entydigt som separator, split_part() är snabbare:

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

Svar för ditt exempel

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


  1. Varför bara väntastatistik inte räcker

  2. Kan en främmande nyckel referera till ett icke-unikt index?

  3. Oracle ORA-12154:TNS:Kunde inte lösa tjänstens namnfel?

  4. Lista över lagrade procedurer/funktioner Mysql Command Line