问题 PostgreSQL错误的排序


我使用PostgreSQL 9.3.3并且我有一个表,其中一列名为title(字符变化(50))。

当我执行以下查询时:

select * from test
order by title asc

我得到了以下结果:

#
A
#Example

为什么“#Example”处于最后位置?在我看来,“#Example”应该处于第二位。


9732
2018-03-20 13:29


起源

这是一个SQL小提琴: sqlfiddle.com/#!15/d819d/1。 - Gordon Linoff
@GordonLinoff:我在SQL Server 2008 R2上测试过,#Example按预期排在第二行 - Moslem Ben Dhaou
什么是数据类型 title 专栏? - Moslem Ben Dhaou
哇,加了一个 desc 到Gordon的sqlfiddle产生'#Example','A','#' - Glenn
Oracle 11.2返回相同的错误顺序 - Dmitry Bychenko


答案:


排序文本的行为(包括 char 和 varchar 以及 text type)取决于 目前的整理 你的语言环境。

查看以前密切相关的问题:

如果您想按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整理处理。


13
2018-03-20 14:03





看来,排序的时候 神谕 以及 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

返回(看:那个DBMS 没有注意 on'A'前面的前缀..'E')

  *
  #
  A
  *B
  #C
  #D
  *E

在你的情况下,Postgres实际上是排序的

'''A' 和 'Example'

如果你放 '#' 在里面 中间 od字符串,行为将是 一样

  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

1
2018-03-20 13:52



但是这首先用哈希来排序'#A','C','#B'。 - Glenn
@Glenn:是的,'#'被忽略,'#A','C','#B'被排序为'#A','#B','C'(因为'A'<'B' '''C') - Dmitry Bychenko
这取决于数据库的整理。当我在本地数据库上运行您的语句(使用UTF8和德语排序规则)时,按以下顺序获取结果: #,#C,#D,*,*B,*E,A - a_horse_with_no_name