运行此查询:
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
这里有什么问题?
答案 0 :(得分:18)
您可以简单地将name
列转换为bytea
数据类型,从而允许整理无关的排序:
SELECT name
FROM folders
ORDER BY name::bytea;
结果:
name
--------------
a test
alphanumeric
test 1
test 10
test 19
test 20
(6 rows)
答案 1 :(得分:5)
您可以通过拆分文本来手动排序,以防有尾随数字,如下所示:
SELECT * FROM sort_test
ORDER BY SUBSTRING(text FROM '^(.*?)( \\d+)?$'),
COALESCE(SUBSTRING(text FROM ' (\\d+)$')::INTEGER, 0);
这将对列文本进行排序,首先是所有字符,可选地排除结尾空格后跟数字,然后排除这些可选数字。
在我的测试中表现良好。
更新使用简单的合并(duh)修复了仅字符串排序。
答案 2 :(得分:4)
所有这些方法都按字母顺序对我的选择进行排序:
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
答案 3 :(得分:2)
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;
所以这一个:
答案 4 :(得分:2)
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中,当我使用按名称查询简单订单时,“名称”列包含以下内容:
查询结果,修改后:
答案 5 :(得分:0)
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;
答案 6 :(得分:0)
上面的一个Vlk的回答对我有很大的帮助,但它只按数字部分排序,在我的情况下排在第二位。我的数据就像(桌子1,桌子2,桌子3 ......)一个字符串部分,一个空格和一个数字部分。 A Vlk的答案中的语法返回按数字排序的数据,并且这是上面唯一的答案。但是当字符串部分不同时(例如桌面3,桌面4,桌子1,桌面5 ...)表1将从桌面2获得第一个。我使用下面的语法修复了这个:
...order by SUBSTRING(name,'\\w+'), SUBSTRINGname FROM '([0-9]+)')::BIGINT ASC;