Postgresql ORDER BY 没有按预期工作

Postgresql ORDER BY not working as expected

让我们用这个简单的例子来说明我面临的问题。

假设这个 table:

CREATE TABLE testing1
(
    id serial NOT NULL,
    word text,
    CONSTRAINT testing1_pkey PRIMARY KEY (id)
);

以及该数据:

insert into testing1 (word) values ('Heliod, God');
insert into testing1 (word) values ('Heliod''s Inter');
insert into testing1 (word) values ('Heliod''s Pilg');
insert into testing1 (word) values ('Heliod, Sun');

然后我想运行这个查询得到按word列排序的结果:

SELECT
    id, word
FROM testing1
WHERE UPPER(word::text) LIKE UPPER('heliod%') 
ORDER BY word asc;

但是看看输出,它不是有序的。我希望行按该顺序排列,使用它们的 ID:2、3、1、4(或者,如果我使用单词的值:Heliod's InterHeliod's PilgHeliod, GodHeliod, Sun)。这是我得到的:

我认为由于我使用的 WHERE 标准,可能有些东西会混淆 postgresql,但如果我只是按行排序,就会发生以下情况:

我是不是漏掉了什么?我在文档中找不到任何关于对包含引号的值进行排序的内容(我怀疑是引号导致了这种行为,因为它们在 postgresql 中具有特殊含义,但我可能错了)。

我正在为我的数据库使用 UTF-8 编码(虽然不确定它是否重要)并且这个问题发生在 Postgresql 版本 12.7 上。

的输出 show lc_ctype;

"en_GB.UTF-8"

和输出 show lc_collate;

"en_GB.UTF-8"

这是对 en_US.UTF-8 中的行进行排序的正确方法。它 'weird'(对习惯 ASCII 的人来说)带有标点符号和空格的东西,跳过第一遍并仅考虑其他绑定值。

如果您不需要这些规则,可以改用 C 排序规则。

的确,我已经尝试了@jjanes 的建议,使用 C 排序规则,输出是我所期望的:

SELECT
    id, word
FROM testing1
ORDER BY word collate "C" ;

真奇怪,我已经使用 postgresql 多年了,但我从未注意到这种行为。

文档中的相关部分:

23.2.2.1. Standard Collations

On all platforms, the collations named default, C, and POSIX are available. > Additional collations may be available depending on operating system support. The default collation selects the LC_COLLATE and LC_CTYPE values specified at database creation time. The C and POSIX collations both specify “traditional C” behavior, in which only the ASCII letters “A” through “Z” are treated as letters, and sorting is done strictly by character code byte values.