How to do sorting on irregular Alphanumeric data in postgres sql

后端 未结 2 1436
清歌不尽
清歌不尽 2020-12-20 04:32

I have the following sample data for a particular column symbol for sample table.

(Update:) The data is not in a regular pattern. Number may occur at any place in be

相关标签:
2条回答
  • 2020-12-20 04:54

    PostgreSQL doesn't offer a number-aware collation that can do "humanized" sorts like "1A, 2A, 3A, ... 10A, 11A, ...". It relies on the operating system for collation, and I'm not aware of any OS that exposes such a collation to applications.

    To do this, you need to split the text according to a pattern and order by the pattern parts, probably using regexp_matches.

    CREATE TABLE Table1 ("symbol" text);
    INSERT INTO Table1 ("symbol") VALUES
        ('COL4A1'),('COL4A3'),('COL8A2'),('COL2A1'),
        ('COL12A1'),('COL12A1'),('COL16A1'),('COL19A1');
    
    WITH matched(symbol, symbol_parts) AS (
      SELECT symbol, regexp_matches(symbol, '(\D*)(\d+)(\D+)(\d+)')
      FROM Table1
    )
    SELECT symbol 
    FROM matched
    ORDER BY symbol_parts[1], symbol_parts[2]::integer,
             symbol_parts[3], symbol_parts[4]::integer;
    
    0 讨论(0)
  • 2020-12-20 04:54
    CREATE OR REPLACE FUNCTION pad_numbers(text)
                  RETURNS text AS
                $BODY$
                    SELECT regexp_replace(
                    regexp_replace(
                      regexp_replace(
                        regexp_replace(
                          $1, 
                          E'(^|\\D)(\\d{1,3}($|\\D))', E'\\1000\\2', 'g'
                        ), E'(^|\\D)(\\d{4,6}($|\\D))', E'\\1000\\2', 'g'
                      ), E'(^|\\D)(\\d{7}($|\\D))', E'\\100\\2', 'g'
                    ), E'(^|\\D)(\\d{8}($|\\D))', E'\\10\\2', 'g'
                  );
                $BODY$
                  LANGUAGE 'sql' VOLATILE;
    
    
    select symbol from sample order by pad_numbers(symbol) asc
    
    0 讨论(0)
提交回复
热议问题