在数据库中,我有以下格式的各种字母数字字符串:
10_asdaasda 100_inkskabsjd 11_kancaascjas 45_aksndsialcn 22_dsdaskjca 100_skdnascbka
我希望他们基本上按照字符串前面的数字排序,然后是字符串名称本身,但是当然,字符被逐一比较,因此按名称排序的结果会产生:
10_asdaasda 100_inkskabsjd 100_skdnascbka 11_kancaascjas 22_dsdaskjca 45_aksndsialcn
而不是我喜欢的订单:
10_asdaasda 11_kancaascjas 22_dsdaskjca 45_aksndsialcn 100_inkskabsjd 100_skdnascbka
老实说,如果字符串按照前面的数字排列,我会很好。我不太熟悉Postgresql,所以我不知道最好的方式是做什么。我会感谢任何帮助!
理想的方法是规范化数据并将列的两个组件分成两个单独的列。一种类型整数,一个文本。
使用当前的表,您可以执行如下所示的操作:
WITH x(t) AS ( VALUES ('10_asdaasda'),('100_inkskabsjd'),('11_kancaascjas'),('45_aksndsialcn'),('22_dsdaskjca'),('100_skdnascbka') ) SELECT t FROM x ORDER BY (substring(t,'^[0-9]+'))::int -- cast to integer,substring(t,'[^0-9_].*$') -- works as text
可以使用相同的substring()
expressions来分割列。
正则表达式有些容错:
>第一个正则表达式从左边选择最长的数字字符串,如果没有找到数字,则返回NULL,因此转换为整数不会出错。
>第二个正则表达式从不是数字的第一个字符或“_”选择字符串的其余部分。
如果下划线是明确的分隔符,split_part()
更快:
ORDER BY (split_part(t,'_',1)::int,split_part(t,2)
回答你的例子
SELECT name FROM naMetable ORDER BY (split_part(name,split_part(name,2)