pgsql 比较数字字符串_postgresql – 使用比较运算符比较postgres中的字符串?

大多数字符串比较默认为所谓的

ASCIIbetical sorting.它将每个字符转换为其ASCII编号(或者可能是UTF-8,其与前7位的ASCII重叠)然后进行排序.这看起来很好……

select 'a' < 'z'; -- true

……但很快就会出错.

select 'a' < 'Z'; -- false

这是因为所有大写字母都在ASCII和UTF-8中的所有小写字母之后.

解决这个问题的简单方法是通过在两侧调用upper或lower来规范化大小写.

select lower('a') < lower('Z'); -- true

ASCIIbetical排序的第二个问题是数字.再次,它开始很好……

select 'a9' < 'a1'; -- true

……但很快就去了锅.

select 'a9' < 'a10'; -- false

ASCIIbetical排序一次比较一个字符. ASCII 9(57)小于ASCII 1(49).

你想要的是一个natural sort,其中字符串部分作为字符串进行比较,数字作为数字进行比较.在SQL中进行自然排序并不是最简单的事情.您需要固定的字段宽度来分别对每个子字符串进行排序,或者可能需要使用正则表达式…

幸运的是,pg_natural_sort_order是Postgres扩展,实现了高效的自然排序.

如果您无法安装扩展,则可以使用存储过程,例如2kan的btrsort.

CREATE FUNCTION btrsort_nextunit(text) RETURNS text AS $$

SELECT

CASE WHEN $1 ~ '^[^0-9]+' THEN

COALESCE( SUBSTR( $1, LENGTH(SUBSTRING($1 FROM '[^0-9]+'))+1 ), '' )

ELSE

COALESCE( SUBSTR( $1, LENGTH(SUBSTRING($1 FROM '[0-9]+'))+1 ), '' )

END

$$LANGUAGE SQL;

CREATE FUNCTION btrsort(text) RETURNS text AS $$

SELECT

CASE WHEN char_length($1)>0 THEN

CASE WHEN $1 ~ '^[^0-9]+' THEN

RPAD(SUBSTR(COALESCE(SUBSTRING($1 FROM '^[^0-9]+'), ''), 1, 12), 12, ' ') || btrsort(btrsort_nextunit($1))

ELSE

LPAD(SUBSTR(COALESCE(SUBSTRING($1 FROM '^[0-9]+'), ''), 1, 12), 12, ' ') || btrsort(btrsort_nextunit($1))

END

ELSE

$1

END

;

$$LANGUAGE SQL;

虽然它没有提供比较运算符,但我不会假装理解它.这允许您按顺序使用它.

select * from things order by btrsort(whatever);

create index things_whatever_btrsort_idx ON things( btrsort(whatever) );

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值