跟随Sivaram Chintalapudi 提出的这个问题,我对在PostgreSQL中对包含多位数字和单词/字母的混合字符串进行自然(或“人性化”)排序 “ 是否可行”感兴趣,没有固定的解决方案字符串中的单词和数字的模式,并且字符串中可能有多个多位数字。
我唯一看到的常规操作是在Mac OS的Finder中,它对包含混合数字和单词的文件名进行自然排序,将“ 20”放在“ 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)函数之类的方法轻松完成。syntax,这种语法是虚构的。
萧十郎
相关分类