2

サンプル テーブルの特定の列シンボルについて、次のサンプル データがあります。

(更新:) データは規則的なパターンではありません。数字は、文字間の任意の場所に出現する可能性があります。

symbol

COL4A1
COL4A3
COL8A2
COL2A1
COL12A1
COL12A1
COL16A1
COL19A1

このデータをデータベースレベルでソートする必要があります。次のクエリを使用しました。

select symbol from sample order by symbol asc

結果は次のとおりです。

COL12A1
COL12A1
COL16A1
COL19A1
COL2A1
COL4A1
COL4A3
COL8A2

しかし、次の方法で注文を取得する必要があります。

COL2A1
COL4A1
COL4A3
COL8A2
COL12A1
COL12A1
COL16A1
COL19A1
4

2 に答える 2

4

PostgreSQL は、「1A、2A、3A、... 10A、11A、...」のような「人間化された」並べ替えを実行できる数値認識照合を提供しません。照合はオペレーティング システムに依存しており、そのような照合をアプリケーションに公開する OS を私は知りません。

これを行うには、パターンに従ってテキストを分割し、パターン パーツごとに並べ替える必要があります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;
于 2012-10-16T14:00:32.227 に答える
2
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
于 2012-10-19T08:57:12.520 に答える