- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
跟进 this question通过 Sivaram Chintalapudi , 我感兴趣的是在 PostgreSQL 中做 natural - or "humanized" - sorting 是否可行"包含多位数字和单词/字母混合的字符串。字符串中没有固定的单词和数字模式,并且一个字符串中可能有多个多位数字。
我见过的唯一经常这样做的地方是在 Mac 操作系统的 Finder 中,它自然地对包含混合数字和单词的文件名进行排序,将“20”放在“3”之后,而不是在它之前。
所需的排序规则将由一种算法生成,该算法将每个字符串在字母数字边界处分成 block ,然后对每个部分进行排序,将具有正常排序规则的字母 block 和数字 block 视为用于排序目的的整数。所以:
'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(..) 结构或不相等条目数的记录。
给定样本数据 in this 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)
功能。唉,这种语法是虚构的。
更新: Blog post on the topic .
最佳答案
基于您的测试数据,但这适用于任意数据。这适用于字符串中任意数量的元素。
注册一个由一个text
组成的复合类型和一个integer
每个数据库值一次。我称之为ai
:
CREATE TYPE ai AS (a text, i int);
诀窍是形成一个 ai
的数组来自列中的每个值。
regexp_matches()
带有图案 (\D*)(\d*)
和 g
选项为字母和数字的每种组合返回一行。加上一个不相关的悬垂行和两个空字符串 '{"",""}'
过滤或抑制它只会增加成本。在将空字符串 ( ''
) 替换为 0
之后,将其聚合到一个数组中在integer
组件(因为 ''
不能转换为 integer
)。
NULL
值首先排序 - 或者你必须对它们进行特殊处理 - 或者在 STRICT
中使用整个 shebang像@Craig 提议的功能。
SELECT data
FROM alnum
ORDER BY ARRAY(SELECT ROW(x[1], CASE x[2] WHEN '' THEN '0' ELSE x[2] END)::ai
FROM regexp_matches(data, '(\D*)(\d*)', 'g') x)
, data;
db<> fiddle here
使用 PostgreSQL 9.1.5 测试,其中 regexp_replace()
行为略有不同。
SELECT data
FROM (
SELECT ctid, data, regexp_matches(data, '(\D*)(\d*)', 'g') AS x
FROM alnum
) x
GROUP BY ctid, data -- ctid as stand-in for a missing pk
ORDER BY regexp_replace (left(data, 1), '[0-9]', '0')
, array_agg(ROW(x[1], CASE x[2] WHEN '' THEN '0' ELSE x[2] END)::ai)
, data -- for special case of trailing 0
添加regexp_replace (left(data, 1), '[1-9]', '0')
作为第一个ORDER BY
项目来处理前导数字和空字符串。
如果特殊字符像
{}()"',
可能会发生,你必须相应地逃避那些。
@Craig 建议使用 ROW
表达式负责这一点。
<罢工>顺便说一句,这不会在 sqlfiddle 中执行,但会在我的数据库集群中执行。 JDBC 无法胜任。 sqlfiddle 提示:
Method org.postgresql.jdbc3.Jdbc3Array.getArrayImpl(long,int,Map) is not yet implemented.
此问题已得到修复:http://sqlfiddle.com/#!17/fad6e/1
关于sql - 混合字数串的人性化或自然数排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12965463/
我不知道引用引用的对象的值如何。顺便说一句,我不是在谈论整数。 我想做这个方法。 swapNN(NaturalNumber j, NaturalNumber n) 我希望交换 j 和 n 的引用,但是
给定一个向量 v w [1] -2 -1 0 1 2 3 4 7 8 9 10 11 12 13 19 20 21 22 23 24 25 最佳答案 另一种方法是 c(t(sapp
给定前 n 个自然数的 k 组合,出于某种原因,我需要在 itertools 返回的那些组合中找到这种组合的位置。 combination(range(1,n),k)(原因是这样我可以使用 list
在根据代码摘录识别复杂性或最坏情况时,我了解什么是大 O 表示法。 在类里面,我被教导说,当谈到复杂性和大 O 表示法时,我们忽略低于 M 的小参数 n 和常数因子 C 。 这是在类里面给我的: In
我需要编写一个算法来解决这个练习,有什么建议吗? 练习: 我们有一个矩形,分成 n x m 个正方形,每个正方形都是自然数。编写一个函数来计算这个矩形内有多少个幻方。 幻方是 k x k (k>=2)
我是一名优秀的程序员,十分优秀!