postgresql - 别名字段上的 Postgres 排序规则

标签 postgresql internationalization collation

我有下表:

CREATE TABLE public_bodies
  ("id" int, "name" varchar(46))
;

INSERT INTO public_bodies
  ("id", "name")
VALUES
  (1, 'Ytre Helgeland District Psychiatric Centre'),
  (2, 'Åfjord Municipality'),
  (3, 'Østfold Hospital')
;

我想运行这个查询:

SELECT public_bodies.id, public_bodies.name AS display_name
FROM public_bodies
ORDER BY display_name COLLATE "en_US";

但是我得到这个错误:

ERROR:  column "display_name" does not exist
LINE 3: ORDER BY display_name COLLATE "en_US";
                 ^

按表名排序效果很好:

SELECT public_bodies.id, public_bodies.name AS display_name
FROM public_bodies
ORDER BY public_bodies.name COLLATE "en_US";

--  id |        display_name
-- ----+--------------------------------------------
--   2 | Åfjord Municipality
--   3 | Østfold Hospital
--   1 | Ytre Helgeland District Psychiatric Centre

按别名排序也可以:

SELECT public_bodies.id, public_bodies.name AS display_name
FROM public_bodies
ORDER BY display_name;

--  id |        display_name
-- ----+--------------------------------------------
--   2 | Åfjord Municipality
--   3 | Østfold Hospital
--   1 | Ytre Helgeland District Psychiatric Centre

在分配别名之前应用 COLLATE 是可行的,但我不明白为什么这与在 ORDER_BY 之后进行整理不同。

SELECT public_bodies.id, public_bodies.name COLLATE "en_US" AS display_name
FROM public_bodies
ORDER BY display_name;

--  id |        display_name
-- ----+--------------------------------------------
--   2 | Åfjord Municipality
--   3 | Østfold Hospital
--   1 | Ytre Helgeland District Psychiatric Centre

Postgres 版本:

SELECT version();
                                               version
-------------------------------------------------------------------------------------------------------------
 PostgreSQL 9.1.12 on x86_64-unknown-linux-gnu, compiled by gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3, 64-bit

我在 SQL fiddle (Postgres 9.3) 上得到了相同的结果。

为什么 Postgres 不能对别名字段进行整理?

最佳答案

这是定义语言的方式。 COLLATE 子句适用于表达式,这种情况不符合条件。

“表达式”是指一些运算符、函数、变量标识符、文字等的集合,它们组合起来产生一个输出值。换句话说,一般类的产生值(value)的“事物”被允许作为函数参数出现,作为 SELECT 字段定义,在 VALUES 列表中,以及等等。

COLLATE 子句可以附加到表达式,表达式可以出现在 ORDER BY 列表中,但这不是唯一的 ORDER BY 列表中允许的事物;您还可以包括 names or positions of output columns , 但这些被解析器视为不同的情况。

需要区别对待它们的原因是查询的输出字段标识符不在 scope 中。在评估表达式时;这就是为什么像 ORDER BY display_name || 这样的东西'x' 返回 column "display_name"does not exist。为了解决这个问题,ORDER BY 列表中的裸字段名在尝试表达式评估之前与输出列表进行比较,但结果是,没有比裸字段名更复杂的东西在此被接受上下文(包括附加的 COLLATE 子句)。

关于postgresql - 别名字段上的 Postgres 排序规则,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31159066/

相关文章:

java - Web 应用程序的国际化

sql-server - 应用程序对字符串的排序方式与数据库不同

php - php 完成的多语言网站

ruby-on-rails - Rails 中的多种货币

sql - 在 Postgres 函数中显示下一个半小时时间点

sql - Postgres SQL Group By 直到下一行不同

java - 在 Java 中使用 MySQL 排序规则

xslt - XSL/Saxon 排序规则/命令行

ruby-on-rails - 关于运行 rake db :seed task 的问题

PostgreSQL - 绑定(bind)变量和日期添加