【问题标题】:postgresql order by desc for string not workingpostgresql order by desc 字符串不起作用
【发布时间】:2016-02-20 14:21:22
【问题描述】:

在 Mac 上使用 postgresql,我试图按降序排列名称,但我注意到如果这两个名称的第一个字母相同,它在尝试排序时不会检查第二个字母。

例如,假设您有以下字符串:

Amen, Alia, Atis,...etc

理想情况下,它们应按以下顺序排列:

Alia, Amen, Atis,..etc

但是 postgresql 只检查第一个字母,似乎没有检查整个字符串。因此postgresql返回的名字顺序是:

Atis, Alia, Amen,..etc 

或者只是一些随机的顺序。我已将数据库排序规则设置为 en_us.utf8。

我尝试使用的简化查询是:

SELECT name 
FROM properties 
ORDER BY name;

如何按整个字符串对 postgresql 进行排序,这可能吗?

更新: 当我在pgadmin III中尝试查询时,我发现它产生了相同的结果,我认为这可能与postgreSQL的配置有关。

我的 db 配置是: 排序规则和字符类型为:en_CA.UTF-8 表空间:pg_default

我在mac上设置的配置有问题吗?

【问题讨论】:

  • @klin 查询是:SELECT name FROM properties LEFT OUTER JOIN 观察(properties.id =observations.id)order by name desc
  • Postgres 确实按所有字母排序(整个列内容)。你检查大写字母了吗? “AZ”比“Aa”先出现。另外,将您的查询添加到问题中。
  • @ChristianB.Almeida 在应用查询之前,所有名称都转换为小写字母,但相同的查询在 windows 上有效,但在 mac 上似乎无效。我不确定它是否与 postgresql 的版本或排序规则有关。
  • 这可能是排序规则的问题。要确定是否如此,请尝试SELECT name FROM properties ORDER BY name COLLATE "C"
  • @klin 我已经尝试过您建议的查询,但它仍然包含不正确的顺序,例如降序或升序,它将“测试”放在“钣金”之前。我不知道该选择哪种排序规则?

标签: java postgresql


【解决方案1】:

我猜您遇到了排序规则和/或不可打印字符的问题。

您可以根据http://www.postgresql.org/docs/9.1/static/collation.html 尝试不同的排序规则:

SELECT name COLLATE "C", name::bytea FROM properties 
LEFT OUTER JOIN observations on properties.id =observations.id order by 1 desc;

您将能够对排序规则(第 1 列)进行试验,并查看 name(第 2 列)中存储的确切内容(十六进制二进制值)。

编辑:在找到this Postgres.app issue 之后,我相当有信心您在 OSX 排序规则支持中遇到了一个错误。要确认,您可以尝试在控制台中使用 sort 对相同的文本进行排序。

我不知道目前是否存在解决方法,但PGDG is aware of the problem 和如果一切顺利,PostgreSQL 9.6 might solve your problem

【讨论】:

  • 我已经尝试过您建议的查询,但它仍然包含不正确的顺序,例如降序或升序,它将“测试”放在“钣金”之前。我不知道该选择哪种排序规则?
  • 好的,如果我理解正确,这发生在 OSX 上。你是如何安装 PostgreSQL 的? postgresapp.com ?您可以尝试其他方式或其他版本吗?另外——这可能会有所帮助:github.com/PostgresApp/PostgresApp/issues/…
【解决方案2】:

Natural order sort这就是你要找的。​​p>

PSQL 函数

CREATE FUNCTION btrsort_nextunit(text) RETURNS text AS $$
SELECT CASE WHEN $1 ~ '[^0-9]+' THEN
COALESCE( SUBSTR( $1, LENGTH(SUBSTRING($1 FROM '[^0-9]+'))+1 ),
'' )
ELSE
COALESCE( SUBSTR( $1, LENGTH(SUBSTRING($1 FROM '[0-9]+'))+1 ),
'' )
END
$$ LANGUAGE SQL;

CREATE FUNCTION btrsort(text, integer) RETURNS text AS $$
SELECT CASE WHEN $2-1>0
THEN
RPAD(SUBSTR(COALESCE(SUBSTRING($1 FROM '^[^0-9]+'), ''), 1, 12), 12, ' ') ||
LPAD(SUBSTR(COALESCE(SUBSTRING(btrsort_nextunit($1) FROM '^[0-9]+'), ''), 1, 12), 12, 0) || btrsort(btrsort_nextunit(btrsort_nextunit($1)), $2-1)
ELSE
RPAD(SUBSTR(COALESCE(SUBSTRING($1 FROM '^[^0-9]+'), ''), 1, 12), 12, ' ') ||
LPAD(SUBSTR(COALESCE(SUBSTRING(btrsort_nextunit($1) FROM '^[0-9]+'), ''), 1, 12), 12, 0)
END
;

$$ LANGUAGE SQL;

CREATE FUNCTION btrsort(text) RETURNS text AS $$
SELECT btrsort($1, 10);
$$ LANGUAGE SQL;

用法

SELECT room_number
FROM (SELECT room_number, btrsort(room_number) AS room_sort
FROM rooms
ORDER BY room_sort) AS foo

结果

room_number
-----------
8
9
9a
10

链接

http://www.postgresql.org/docs/8.0/interactive/queries-order.html http://2kan.tumblr.com/post/361326656/postgres-natural-ordering

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-22
    • 1970-01-01
    • 1970-01-01
    • 2015-02-26
    • 2017-12-05
    • 2021-07-14
    • 1970-01-01
    相关资源
    最近更新 更多