18

运行此查询:

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

这里有什么问题?

4

7 回答 7

27

您可以简单地将name列转换为bytea允许与排序无关的排序的数据类型:

SELECT name
FROM folders
ORDER BY name::bytea;

结果:

     name     
--------------
 a test
 alphanumeric
 test 1
 test 10
 test 19
 test 20
(6 rows)
于 2011-08-10T23:17:37.723 回答
15

所有这些方法都按字母顺序对我的选择进行了排序:

test 1
test 10
test 2
test 20

该解决方案对我有用(lc_collat​​e:'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
于 2015-09-04T06:49:52.430 回答
12
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 中,当我使用简单的按名称排序查询时,名称列包含以下内容:

  • 1
  • 10
  • 2
  • 21
  • 一种
  • A1
  • A11
  • A5
  • B2
  • B22
  • B3
  • 米1
  • 中号 11
  • 米2

查询结果,修改后:

  • 1
  • 2
  • 10
  • 21
  • 一种
  • A1
  • A5
  • A11
  • B2
  • B3
  • B22
  • 米1
  • 米2
  • 中号 11
于 2019-08-09T09:29:51.370 回答
8

如果有尾随数字,您可以通过拆分文本手动排序,如下所示:

SELECT * FROM sort_test
ORDER BY SUBSTRING(text FROM '^(.*?)( \\d+)?$'),
         COALESCE(SUBSTRING(text FROM ' (\\d+)$')::INTEGER, 0);

这将按列文本排序,首先按所有字符(可选地不包括结尾空格,后跟数字),然后按这些可选数字。

在我的测试中运行良好。

更新使用简单的合并(duh)修复了仅字符串排序。

于 2011-08-10T23:04:27.617 回答
4

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;

所以这个:

  1. 提取字符串中的第一个数字,或使用 99999999。
  2. 提取可能的第一个数字后面的字符串。
  3. 提取尾随数字,或使用 0。
于 2012-02-28T13:33:16.253 回答
3

上面 Vlk 的回答对我有很大帮助,但它仅按数字部分对项目进行排序,在我的情况下排在第二位。我的数据就像(办公桌 1、办公桌 2、办公桌 3 ...)一个字符串部分、一个空格和一个数字部分。A Vlk 的答案中的语法返回了按数字排序的数据,这是上面唯一的答案。但是,当字符串部分不同时(例如,桌子 3、桌子 4、桌子 1、桌子 5...)桌子 1 会首先从桌子 2 获得。我使用以下语法修复了这个问题:

    ...order by SUBSTRING(name,'\\w+'), SUBSTRINGname FROM '([0-9]+)')::BIGINT ASC;
于 2017-10-17T15:16:01.347 回答
1

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;
于 2014-03-11T16:47:32.253 回答