sql >> Database >  >> RDS >> PostgreSQL

Alfanumeriek sorteren met PostgreSQL

De ideale manier zou zijn om te normaliseren uw gegevens en splits de twee componenten van de kolom in twee afzonderlijke kolommen. Een van het type integer , één text .

Met de huidige tabel kun je zoiets doen als hier gedemonstreerd:

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

Dezelfde substring() uitdrukkingen kunnen worden gebruikt om de kolom te splitsen.

De reguliere expressies zijn enigszins fouttolerant:

  • De eerste regex kiest de langste numerieke reeks van links, NULL als er geen cijfers worden gevonden, dus de cast naar integer kan niet fout gaan.

  • De tweede regex kiest de rest van de tekenreeks uit het eerste teken dat geen cijfer of '_' is.

Als het onderstrepingsteken toch ondubbelzinnig als scheidingsteken is, split_part() is sneller:

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

Antwoord voor uw voorbeeld

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


  1. Converteer queryresultaten naar een door komma's gescheiden lijst in MariaDB

  2. Slaapstand, id, orakel, reeks

  3. ID's van meerdere rijen invoegen in psycopg2

  4. SQL Server 2016:OLTP-verbeteringen in het geheugen