别名字段上的 Postgres 排序规则
Posted
技术标签:
【中文标题】别名字段上的 Postgres 排序规则【英文标题】:Postgres collation on aliased field 【发布时间】:2015-09-18 11:27:24 【问题描述】:我有下表:
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 不能对别名字段进行整理?
【问题讨论】:
在 Postgresql 中你可能根本不能在 order 子句中使用别名 刚刚更新了问题 - 按别名排序而不进行任何排序都可以。 闻起来像虫子。您是否在当前版本 9.4.4 中尝试过? 9.4.4 也不行。 【参考方案1】:这是定义语言的方式。 COLLATE
子句适用于表达式,这种情况不符合条件。
“表达式”是指一些运算符、函数、变量标识符、文字等的集合,它们组合起来产生一个输出值。换句话说,产生价值的“事物”的一般类,允许作为函数参数、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
子句)。
【讨论】:
以上是关于别名字段上的 Postgres 排序规则的主要内容,如果未能解决你的问题,请参考以下文章
在 Postgres 上更改排序规则(保持编码)是不是安全?
使用 pg_dump 将 Postgres 从 Windows 迁移到 Linux 时如何选择正确的排序规则来创建数据库?