与 postgresql 的奇怪排序
Strange collation with postgresql
我注意到 postgresql-9.5 有一个奇怪的整理问题,因为它向 Python 脚本提供了不同的输出。据我了解,通常在排序时从左到右一次比较一个字符:
select 'ab' < 'ac';
t
select 'abX' < 'ac';
t
因此,如果您将 'X' 添加到上面的左侧字符串,则无关紧要。
所以我很惊讶这不适用于 space 和破折号之间的比较:
select 'a ' < 'a-';
t
select 'a X' < 'a-';
f
这是一个错误还是有什么办法解决这个问题;我希望上面的最后一条语句也 return 为真。
[接受@laurenz-albe 的回答后编辑]
show lc_collate;
en_US.UTF-8
如果我在 Python 中按 unicode 进行排序,我会得到类似的结果,所以我认为这不是 postgresql 中的错误,而是 unicode 归类规范中的错误!:
>>> import locale; locale.setlocale(locale.LC_ALL, "")
'en_US.UTF-8'
>>> l = ['ac', 'ab']; sorted(l) == sorted(l, cmp=locale.strcoll)
True
>>> l = ['ac', 'abX']; sorted(l) == sorted(l, cmp=locale.strcoll)
True
>>> l = ['ac', 'abX']; sorted(l) == sorted(l, cmp=locale.strcoll)
True
>>> l = ['a-', 'a X']; sorted(l) == sorted(l, cmp=locale.strcoll)
False
>>> sorted(l), sorted(l, cmp=locale.strcoll)
(['a X', 'a-'], ['a-', 'a X'])
使用排序规则比较字符。您可以使用 SQL 命令
SHOW lc_collate;
查看您的默认排序规则。
PostgreSQL 使用操作系统的排序规则,因此比较的结果通常取决于操作系统。
要强制按字节进行 ASCII 比较,请使用 C 排序规则
test=> SELECT 'a X' COLLATE "C" < 'a-';
?column?
----------
t
(1 row)
或字节比较运算符
test=> SELECT 'a X' ~<~ 'a-';
?column?
----------
t
(1 row)
我注意到 postgresql-9.5 有一个奇怪的整理问题,因为它向 Python 脚本提供了不同的输出。据我了解,通常在排序时从左到右一次比较一个字符:
select 'ab' < 'ac';
t
select 'abX' < 'ac';
t
因此,如果您将 'X' 添加到上面的左侧字符串,则无关紧要。
所以我很惊讶这不适用于 space 和破折号之间的比较:
select 'a ' < 'a-';
t
select 'a X' < 'a-';
f
这是一个错误还是有什么办法解决这个问题;我希望上面的最后一条语句也 return 为真。
[接受@laurenz-albe 的回答后编辑]
show lc_collate;
en_US.UTF-8
如果我在 Python 中按 unicode 进行排序,我会得到类似的结果,所以我认为这不是 postgresql 中的错误,而是 unicode 归类规范中的错误!:
>>> import locale; locale.setlocale(locale.LC_ALL, "")
'en_US.UTF-8'
>>> l = ['ac', 'ab']; sorted(l) == sorted(l, cmp=locale.strcoll)
True
>>> l = ['ac', 'abX']; sorted(l) == sorted(l, cmp=locale.strcoll)
True
>>> l = ['ac', 'abX']; sorted(l) == sorted(l, cmp=locale.strcoll)
True
>>> l = ['a-', 'a X']; sorted(l) == sorted(l, cmp=locale.strcoll)
False
>>> sorted(l), sorted(l, cmp=locale.strcoll)
(['a X', 'a-'], ['a-', 'a X'])
使用排序规则比较字符。您可以使用 SQL 命令
SHOW lc_collate;
查看您的默认排序规则。
PostgreSQL 使用操作系统的排序规则,因此比较的结果通常取决于操作系统。
要强制按字节进行 ASCII 比较,请使用 C 排序规则
test=> SELECT 'a X' COLLATE "C" < 'a-';
?column?
----------
t
(1 row)
或字节比较运算符
test=> SELECT 'a X' ~<~ 'a-';
?column?
----------
t
(1 row)