我使用PostgreSQL 9.3.3,我有一个表,一列名为title(字符变化(50))。
当我执行了以下查询:
select * from test
order by title asc
我得到了以下结果:
#
A
#Example
为什么"#Example"在最后一个位置?在我看来"#Example"应该放在第二个位置
文本(包括char
和varchar
以及text
类型)的排序行为取决于您的区域设置的当前排序。
参见前面密切相关的问题:
- <
- PostgreSQL类/gh>
- https://stackoverflow.com/q/21006868/398670
如果希望按照ASCII值进行简单排序,而不是按照本地语言规则进行适当的本地化排序,则可以使用COLLATE
子句
select *
from test
order by title COLLATE "C" ASC
或全局更改数据库排序(需要转储和重新加载,或完全重新索引)。在我的Fedora 19 Linux系统上,我得到以下结果:
regress=> SHOW lc_collate;
lc_collate
-------------
en_US.UTF-8
(1 row)
regress=> WITH v(title) AS (VALUES ('#a'), ('a'), ('#'), ('a#a'), ('a#'))
SELECT title FROM v ORDER BY title ASC;
title
-------
#
a
#a
a#
a#a
(5 rows)
regress=> WITH v(title) AS (VALUES ('#a'), ('a'), ('#'), ('a#a'), ('a#'))
SELECT title FROM v ORDER BY title COLLATE "C" ASC;
title
-------
#
#a
a
a#
a#a
(5 rows)
PostgreSQL使用操作系统的排序支持,因此结果可能因主机操作系统的不同而略有不同。特别是,至少某些版本的Mac OS X已经严重破坏了unicode排序处理。
似乎,当排序Oracle以及Postgres时,只需忽略 非alpha数字字符,例如
select '*'
union all
select '#'
union all
select 'A'
union all
select '*E'
union all
select '*B'
union all
select '#C'
union all
select '#D'
order by 1 asc
返回(看:DBMS 不注意在'A'. 'E'之前的前缀)
*
#
A
*B
#C
#D
*E
在你的例子中,Postgres实际上排序的是
''
、'A'
、'Example'
如果你把'#'
放在字符串的中间,行为将是相同的:
select 'A#B'
union all
select 'AC'
union all
select 'A#D'
union all
select 'AE'
order by 1 asc
返回(忽略#
,因此实际上比较'AB', 'AC', 'AD'
和'AE'
)
A#B
AC
A#D
AE
要更改的比较规则,您应该使用排序,例如
select '#' collate "POSIX"
union all
select 'A' collate "POSIX"
union all
select '#Example' collate "POSIX"
order by 1 asc
返回(在您的情况下需要)
#
#Example
A