我使用PostgreSQL 9.3.3并且我有一个表,其中一列名为title(字符变化(50)).
当我执行以下查询时:
select * from test
order by title asc
Run Code Online (Sandbox Code Playgroud)
我得到了以下结果:
#
A
#Example
Run Code Online (Sandbox Code Playgroud)
为什么"#Example"处于最后位置?在我看来,"#Example"应该处于第二位.
Cra*_*ger 15
文本(包括排序行为char,并varchar还有text类型)取决于当前归类你的语言环境.
查看以前密切相关的问题:
如果要按ASCII值进行简单排序,而不是遵循本地语言规则进行正确的本地化排序,则可以使用该COLLATE子句
select *
from test
order by title COLLATE "C" ASC
Run Code Online (Sandbox Code Playgroud)
或全局更改数据库排序规则(需要转储和重新加载,或完全重新索引).在我的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)
Run Code Online (Sandbox Code Playgroud)
PostgreSQL使用您的操作系统的排序规则支持,因此结果可能会从主机操作系统到主机操作系统略有不同.特别是,至少某些版本的Mac OS X显着破坏了unicode整理处理.
看来,在对Oracle和Postgres进行排序时,只是忽略 非字母数字字符,例如
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
Run Code Online (Sandbox Code Playgroud)
返回(看:DBMS不关注'A'..'E' 之前的前缀)
*
#
A
*B
#C
#D
*E
Run Code Online (Sandbox Code Playgroud)
在你的情况下,Postgres 实际排序的是
'','A'和'Example'
如果将字符串放在中间,行为将'#'是相同的:
select 'A#B'
union all
select 'AC'
union all
select 'A#D'
union all
select 'AE'
order by 1 asc
Run Code Online (Sandbox Code Playgroud)
返回(#被忽略,所以'AB', 'AC', 'AD'和'AE'实际比较)
A#B
AC
A#D
AE
Run Code Online (Sandbox Code Playgroud)
要更改比较规则,您应该使用collation,例如
select '#' collate "POSIX"
union all
select 'A' collate "POSIX"
union all
select '#Example' collate "POSIX"
order by 1 asc
Run Code Online (Sandbox Code Playgroud)
退货(根据您的情况要求)
#
#Example
A
Run Code Online (Sandbox Code Playgroud)