Alphanumeric sorting with PostgreSQL

后端 未结 4 1683
鱼传尺愫
鱼传尺愫 2020-11-30 02:49

In the database, I have various alpha-numeric strings in the following format:

10_asdaasda
100_inkskabsjd
11_kancaascjas
45_aksndsialcn
22_dsdaskjca
100_skdn         


        
4条回答
  •  南笙
    南笙 (楼主)
    2020-11-30 03:07

    The ideal way would be to normalize your data and split the two components of the column into two individual columns. One of type integer, one text.

    With the current table, you can do something like demonstrated here:

    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
    

    The same substring() expressions can be used to split the column.

    The regular expressions are somewhat fault tolerant:

    • The first regex picks the longest numeric string from the left, NULL if no digits are found, so the cast to integer can't go wrong.

    • The second regex picks the rest of the string from the first character that is not a digit or '_'.

    If the underscore is unambiguous as separator anyway, split_part() is faster:

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

    Answer for your example

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

提交回复
热议问题