use*_*055 24 sql sorting postgresql natural-sort sql-order-by
在数据库中,我有以下格式的各种字母数字字符串:
10_asdaasda
100_inkskabsjd
11_kancaascjas
45_aksndsialcn
22_dsdaskjca
100_skdnascbka
Run Code Online (Sandbox Code Playgroud)
我希望它们基本上按字符串前面的数字排序,然后按字符串名称本身排序,但当然,字符会逐个进行比较,因此Order by name的结果会产生:
10_asdaasda
100_inkskabsjd
100_skdnascbka
11_kancaascjas
22_dsdaskjca
45_aksndsialcn
Run Code Online (Sandbox Code Playgroud)
而不是我更喜欢的顺序:
10_asdaasda
11_kancaascjas
22_dsdaskjca
45_aksndsialcn
100_inkskabsjd
100_skdnascbka
Run Code Online (Sandbox Code Playgroud)
老实说,如果字符串只按前面的数字排序,我会没事的.我对PostgreSQL不太熟悉,所以我不确定最好的方法是什么.我很感激任何帮助!
Erw*_*ter 36
理想的方法是规范化数据并将列的两个组件拆分为两个单独的列.其中一种integer
,一种text
.
使用当前表,您可以执行以下演示:
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
Run Code Online (Sandbox Code Playgroud)
可以使用相同的substring()
表达式来拆分列.
正则表达式有点容错:
第一个正则表达式从左边选择最长的数字字符串,NULL
如果没有找到数字,那么转换为integer
不会出错.
第二个正则表达式从第一个不是数字或'_'的字符中选取字符串的其余部分.
如果下划线无论如何都是明确的分隔符,split_part()
则更快:
ORDER BY (split_part(t, '_', 1)::int
,split_part(t, '_', 2)
Run Code Online (Sandbox Code Playgroud)
SELECT name
FROM nametable
ORDER BY (split_part(name, '_', 1)::int
,split_part(name, '_', 2)
Run Code Online (Sandbox Code Playgroud)
小智 6
您可以将正则表达式与子字符串一起使用
order by substring(column, '^[0-9]+')::int, substring(column, '[^0-9]*$')
Run Code Online (Sandbox Code Playgroud)