运行此查询:
select name from folders order by name
返回这些结果:
alphanumeric
a test
test 20
test 19
test 1
test 10
但我期望:
a test
alphanumeric
test 1
test 10
test 19
test 20
这里有什么问题?
运行此查询:
select name from folders order by name
返回这些结果:
alphanumeric
a test
test 20
test 19
test 1
test 10
但我期望:
a test
alphanumeric
test 1
test 10
test 19
test 20
这里有什么问题?
您可以简单地将name
列转换为bytea
允许与排序无关的排序的数据类型:
SELECT name
FROM folders
ORDER BY name::bytea;
结果:
name
--------------
a test
alphanumeric
test 1
test 10
test 19
test 20
(6 rows)
所有这些方法都按字母顺序对我的选择进行了排序:
test 1
test 10
test 2
test 20
该解决方案对我有用(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
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";
注意:根据需要转义正则表达式,在某些语言中,您必须再添加一个“\”。
在我的 Postgres DB 中,当我使用简单的按名称排序查询时,名称列包含以下内容:
查询结果,修改后:
如果有尾随数字,您可以通过拆分文本手动排序,如下所示:
SELECT * FROM sort_test
ORDER BY SUBSTRING(text FROM '^(.*?)( \\d+)?$'),
COALESCE(SUBSTRING(text FROM ' (\\d+)$')::INTEGER, 0);
这将按列文本排序,首先按所有字符(可选地不包括结尾空格,后跟数字),然后按这些可选数字。
在我的测试中运行良好。
更新使用简单的合并(duh)修复了仅字符串排序。
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;
所以这个:
上面 Vlk 的回答对我有很大帮助,但它仅按数字部分对项目进行排序,在我的情况下排在第二位。我的数据就像(办公桌 1、办公桌 2、办公桌 3 ...)一个字符串部分、一个空格和一个数字部分。A Vlk 的答案中的语法返回了按数字排序的数据,这是上面唯一的答案。但是,当字符串部分不同时(例如,桌子 3、桌子 4、桌子 1、桌子 5...)桌子 1 会首先从桌子 2 获得。我使用以下语法修复了这个问题:
...order by SUBSTRING(name,'\\w+'), SUBSTRINGname FROM '([0-9]+)')::BIGINT ASC;
Tor 的最后一条 SQL 对我有用。但是,如果您从 php 调用此代码,则需要添加额外的斜杠。
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;