【问题标题】:Correct collate in Postgresql 9.1在 Postgresql 9.1 中正确排序
【发布时间】:2012-05-19 12:18:33
【问题描述】:

我已经使用 lc_collat​​e、lc_ctype = es_PE.UTF-8 安装了 Ubuntu 12.04 和 PG 9.1,但它没有按预期进行整理 (u = ü = ú = U = Ú = Ü)。

如果我:

CREATE TABLE testing (id integer PRIMARY KEY, dad text, mum text, name text);
INSERT INTO testing VALUES
  (1, 'león','valencia', 'josé'),
  (2, 'leon', 'mendoza', 'juan'),
  (3, 'león', 'valárd', 'jose'),
  (4, 'león','válencia', 'jos'),
  (5, 'león', 'mendoza', 'jua'),
  (6, 'leon', 'valencia', 'josie'),
  (7, 'león', 'valencia', 'josie'),
  (8, 'leo','zara', 'juan'),
  (9, 'león','Valencia', 'jos');
SELECT * FROM testing ORDER BY dad, mum, name;

然后我得到:

 id | dad  |   mum    | name
----+------+----------+-------
  8 | leo  | zara     | juan
  2 | leon | mendoza  | juan
  6 | leon | valencia | josie
  5 | león | mendoza  | jua
  3 | león | valárd   | jose
  1 | león | valencia | josé
  7 | león | valencia | josie
  9 | león | Valencia | jos
  4 | león | válencia | jos
(9 rows)

如何配置才能获取:

 id | dad  |   mum    | name
----+------+----------+-------
  8 | leo  | zara     | juan
  5 | león | mendoza  | jua
  2 | leon | mendoza  | juan
  3 | león | valárd   | jose
  9 | león | Valencia | jos
  4 | león | válencia | jos
  1 | león | valencia | josé
  7 | león | valencia | josie
  6 | leon | valencia | josie
(9 rows)

这是在 MySQL 中完成的,没有任何问题。但我无法在 PG 9.1 中配置它

提前谢谢...

【问题讨论】:

  • 只是为了确认一下,当您在数据库中运行 SHOW lc_collate;SHOW lc_ctype; 时,都返回 es_PE.UTF-8?
  • 是的@kgrittn,即使集群也是这样创建的。阅读您的答案,您提出的第二种形式将“leo”放在最后,这是意料之外的。我会调查以测试您的第一个提案,但 Make ú = u 不是整理的目的吗?在这种情况下,它应该使用第二个字段,然后是第三个字段来排序......因为它是 MySQL 正确执行的。

标签: postgresql collation postgresql-9.1


【解决方案1】:

PostgreSQL 使用操作系统的排序规则;但是,它永远不会让不同值的顺序随机化——如果根据排序规则,两个字符串相等,它本质上会退回到 C 排序规则作为决胜局。

您有两种可能性:您可以对没有重音的字符串进行排序,或者您可以对字符串列的串联进行排序。

对于第一个选项,您需要在数据库中安装 unaccent 功能,如下所示:

CREATE EXTENSION unaccent;

已经完成了,你可以运行这个:

SELECT * FROM testing ORDER BY unaccent(dad), unaccent(mum), unaccent(name);

对于第二个选项,您不需要安装任何其他东西,但您可以运行以下内容:

SELECT * FROM testing ORDER BY dad || ', ' || mum || ' ' || name;

在我们的商店中,我们做了类似的事情,但我们使用“生成的列”来确保一致性。大致如下:

CREATE FUNCTION search_name(rec testing)
  RETURNS text
  LANGUAGE SQL
AS $$ SELECT $1.dad || ', ' || $1.mum || ' ' || $1.name; $$;

这允许像这样更简单的选择:

SELECT * FROM testing t ORDER BY t.search_name;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-10-11
    • 2021-10-26
    • 1970-01-01
    • 2012-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多