我有下面的库存股票代码表,并希望获取最高的字母数字值 * AR-JS-20 *。当我说"最高"时,我的意思是首先排序字母顺序,然后考虑数字,因此 * AR-JS-20 * 高于 * AL-JS-20 *。
顺便说一句,我不想把任何东西分成几个部分,因为它是未知的符号供应商将发送我在未来。我只是想一个字母数字排序像你排序计算机目录的名称。其中破折号,下划线,星号等来第一,然后数字,字母最后与级联优先级的第一个字符在符号中有最大的权重,然后第二个字符等等。
注:此问题已编辑,因此下面的一些答案不再适用。
AL-JS-20
AR-JS-20
AR-JS-9
AB-JS-8
AA-JS-1
1A-LM-30
2BA2-1
45HT
因此,理想情况下,如果按照我的要求对该表进行排序,它将如下所示
AR-JS-20
AR-JS-9
AB-JS-8
AL-JS-20
AA-JS-1
45HT
2BA2-1
1A-LM-30
但是,当我使用这个查询时:
select max(symbol) from stock
我得到:
一个三个三个一个
我也试过:
select max(symbol::bytea) from stock
但这会触发错误:
函数max(bytea)不存在
2条答案
按热度按时间pobjuy321#
这组问题有专门的标签:natural-sort(我现在添加了它。)
理想情况下,字符串部分和数值部分存储在单独的列中。
当你被那些不幸的符号困住的时候...
如果您的符号像示例所建议的那样规则,那么普通的
left()
和split_part()
就可以完成这项工作:参见:
^
...定位到字符串的开头$
...定位到字符串的末尾\D
...非数字的类速记\d
...数字的类速记只取(尾部)数字,我们可以安全地转换为
integer
(假设数字〈2^31),并相应地排序。如果可能缺少任何部件,则添加
NULLS LAST
,或者列可能为NULL
。rekjcdws2#
指定一个自定义
order by
,它将修剪最后一个-
之前的所有内容,并将剩余的数字转换为int
,然后取第一个:参见live demo。
这适用于代码开头和结尾的数字:
regexp_replace(stock_code, '-?[0-9]+-?', '')
"删除"数字和任何相邻的破折号regexp_replace(stock_code, '[^0-9]', '')
"删除"所有非数字