【问题标题】:Incorrect sort/collation/order with spaces in Postgresql 9.4Postgresql 9.4 中带有空格的排序/整理/顺序不正确
【发布时间】:2016-04-04 22:15:16
【问题描述】:

我使用的是 Postgresql 9.4.5。当我去 psql 并运行 \l 我得到

Encoding is UTF8
Collate is en_US.UTF-8 
cCtype is en_US.UTF-8

我有一个 products 表,其中有一个 name 列,该列具有以下名称:

T-700A Grouped
T-700 AGrouped
T-700A Halved
T-700 Whole

当我在 pql 中执行以下 SQL 时

SELECT name FROM products WHERE name LIKE '%T-700%' ORDER By name ASC;

我得到以下输出

T-700A Grouped
T-700 AGrouped
T-700A Halved
T-700 Whole

这种排序看起来不自然。我希望得到

T-700 AGrouped
T-700 Whole
T-700A Grouped
T-700A Halved

似乎 Postgres 并没有按照我预期的方式处理空间。谁能解释正在发生的事情并提出解决此问题的方法?

【问题讨论】:

  • this 对你有用吗?
  • 是的,这看起来像一个类似的问题。不过,他们并没有真正以全球方式解决问题。我希望能够以默认情况下所有文本列的行为方式相同的方式设置数据库。

标签: postgresql postgresql-9.4


【解决方案1】:

Unix/Linux SE, a friendly expert explained 上,您看到的是对 Unicode 进行排序的正确方法。基本上,standard 正在尝试排序:

di Silva Fred                  di Silva Fred
di Silva John                  diSilva Fred
diSilva Fred                   disílva Fred
diSilva John         ->        di Silva John
disílva Fred                   diSilva John
disílva John                   disílva John

现在,如果空格和字母一样重要,排序就无法区分 Fred 和 John 的各种相同拼写。所以发生的事情是它首先没有空格进行排序。然后在第二遍中,对没有空格的相同字符串进行排序。 (这是一种简化,真正的算法看起来相当复杂,为空格、重音符号和不可打印字符分配不同级别的优先级。)

您可以通过设置绕过 Unicode 排序规则:

export LC_ALL=C

或者在 Postgres 中通过转换为字节数组进行排序:

order by name::bytea

或者(来自Kiln's answer)通过指定C 排序规则:

order by name collate "C"

或者通过更改列的默认排序规则:

alter table products alter column name type text collate "C";

【讨论】:

  • 我在linux / unix stackexchange 上问过这个问题...也许 unix 大师知道答案:)
  • 这只是救了我几个小时
  • 给定的解决方案适用于英语,但如果我仍然需要按区域设置相关规则排序怎么办?我需要对单词进行 unicode 排序。 “休假”必须在“一”之前。
  • 应该注意这可能会对索引的使用产生负面的性能影响。 dba.stackexchange.com/questions/260267/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-10-11
  • 2021-10-26
  • 1970-01-01
  • 1970-01-01
  • 2019-09-16
  • 1970-01-01
  • 2012-02-24
相关资源
最近更新 更多