el_*_*ick 12 sorting postgresql alphanumeric
运行此查询:
select name from folders order by name
Run Code Online (Sandbox Code Playgroud)
返回这些结果:
alphanumeric
a test
test 20
test 19
test 1
test 10
Run Code Online (Sandbox Code Playgroud)
但我预计:
a test
alphanumeric
test 1
test 10
test 19
test 20
Run Code Online (Sandbox Code Playgroud)
这有什么不对?
Grz*_*ski 21
您可以简单地将name列转换bytea为允许整理不可知顺序的数据类型:
SELECT name
FROM folders
ORDER BY name::bytea;
Run Code Online (Sandbox Code Playgroud)
结果:
name
--------------
a test
alphanumeric
test 1
test 10
test 19
test 20
(6 rows)
Run Code Online (Sandbox Code Playgroud)
小智 8
所有这些方法都按字母顺序对我的选择进行了排序:
test 1
test 10
test 2
test 20
Run Code Online (Sandbox Code Playgroud)
这个解决方案对我有用(lc_collate:'ru_RU.UTF8'):
SELECT name
FROM folders
ORDER BY SUBSTRING(name FROM '([0-9]+)')::BIGINT ASC, name;
test 1
test 2
test 10
test 20
Run Code Online (Sandbox Code Playgroud)
select * from "public"."directory" where "directoryId" = 17888 order by
COALESCE(SUBSTRING("name" FROM '^(\d+)')::INTEGER, 99999999),
SUBSTRING("name" FROM '[a-zA-z_-]+'),
COALESCE(SUBSTRING("name" FROM '(\d+)$')::INTEGER, 0),
"name";
Run Code Online (Sandbox Code Playgroud)
注意:根据需要转义正则表达式,在某些语言中,您必须再添加一个“\”。
在我的 Postgres 数据库中,当我使用按名称查询的简单顺序时,名称列包含以下内容:
查询结果,修改后:
如果有尾随数字,您可以通过拆分文本来手动排序,如下所示:
SELECT * FROM sort_test
ORDER BY SUBSTRING(text FROM '^(.*?)( \\d+)?$'),
COALESCE(SUBSTRING(text FROM ' (\\d+)$')::INTEGER, 0);
Run Code Online (Sandbox Code Playgroud)
这将对列文本进行排序,首先是所有字符(可选地,不包括结尾空格,后跟数字),然后是那些可选数字。
在我的测试中表现良好。
更新修复了具有简单合并(duh)的仅字符串排序。
小智 5
OverZealous 答案对我有帮助,但如果数据库中的字符串以数字开头,后跟附加字符,则不起作用。
以下对我有用:
SELECT name
FROM folders
ORDER BY
COALESCE(SUBSTRING(name FROM '^(\\d+)')::INTEGER, 99999999),
SUBSTRING(name FROM '^\\d* *(.*?)( \\d+)?$'),
COALESCE(SUBSTRING(name FROM ' (\\d+)$')::INTEGER, 0),
name;
Run Code Online (Sandbox Code Playgroud)
所以这个: