Sivaram Chintalapudiによるこの質問のフォローアップとして、複数桁の数字と単語/文字の混合を含む文字列の「自然な」または「人間化された」ソートを行うことが PostgreSQL で実用的かどうかに興味があります。文字列内の単語と数字のパターン、および文字列内に複数桁の数字が複数存在する場合があります。
これが日常的に行われているのを私が見た唯一の場所は、Mac OS の Finder です。これは、数字と単語が混在するファイル名を自然にソートし、「20」を「3」の前ではなく「3」の後に配置します。
必要な照合順序は、各文字列を文字と数字の境界でブロックに分割し、各部分を並べ替えて、文字ブロックを通常の照合で、数字ブロックを照合目的の整数として扱うアルゴリズムによって生成されます。そう:
'AAA2fred'
('AAA',2,'fred')
となる'AAA10bob'
でしょう('AAA',10,'bob')
。これらは、必要に応じて並べ替えることができます。
regress=# WITH dat AS ( VALUES ('AAA',2,'fred'), ('AAA',10,'bob') )
regress-# SELECT dat FROM dat ORDER BY dat;
dat
--------------
(AAA,2,fred)
(AAA,10,bob)
(2 rows)
通常の文字列照合順序と比較して:
regress=# WITH dat AS ( VALUES ('AAA2fred'), ('AAA10bob') )
regress-# SELECT dat FROM dat ORDER BY dat;
dat
------------
(AAA10bob)
(AAA2fred)
(2 rows)
ただし、Pg は ROW(..) コンストラクトまたはエントリ数が等しくないレコードを比較しないため、レコード比較アプローチは一般化されません。
この SQLFiddleのサンプル データを指定すると、デフォルトの en_AU.UTF-8 照合順序が生成されます。
1A, 10A, 2A, AAA10B, AAA11B, AAA1BB, AAA20B, AAA21B, X10C10, X10C2, X1C1, X1C10, X1C3, X1C30, X1C4, X2C1
でも私はしたい:
1A, 2A, 10A, AAA1BB, AAA10B, AAA11B, AAA20B, AAA21B, X1C1, X1C3, X1C4, X1C10, X1C30, X2C1, X10C10, X10C2
現在、PostgreSQL 9.1 を使用していますが、9.2 のみの提案で問題ありません。効率的な文字列分割方法を実現する方法と、説明されている文字列と数値の交互照合で結果の分割データを比較する方法についてのアドバイスに興味があります。または、もちろん、文字列の分割を必要としない、まったく異なる、より優れたアプローチで。
PostgreSQL はコンパレータ関数をサポートしていないようです。それ以外の場合は、再帰コンパレータと関数のようなものを使用してかなり簡単に実行できORDER USING comparator_fn
ますcomparator(text,text)
。残念ながら、その構文は架空のものです。
更新: トピックに関するブログ投稿。