PostgreSQL错误排序

PostgreSQL错误排序,sql,postgresql,Sql,Postgresql,我使用PostgreSQL 9.3.3,我有一个表,其中一列名为title(字符变化(50)) 当我执行以下查询时: select * from test order by title asc 我得到了以下结果: # A #Example regress=> SHOW lc_collate; lc_collate ------------- en_US.UTF-8 (1 row) regress=> WITH v(title) AS (VALUES ('#a'), ('

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

当我执行以下查询时:

select * from test
order by title asc
我得到了以下结果:

#
A
#Example
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)

为什么“#示例”位于最后一个位置?我认为“#示例”应该排在第二位。

似乎,在对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
  select '#' collate "POSIX"
   union all
  select 'A' collate "POSIX"
   union all
  select '#Example' collate "POSIX"
order by 1 asc
返回(注意:DBMS不注意“A”…“E”之前的前缀)

在你的例子中,Postgres实际排序的是

'
'A'
'Example'

如果在字符串的中间放置<代码> '>代码>代码,行为将是相同的:

返回(
被忽略,因此实际比较了
'AB',AC',AD'
'AE'

要更改比较规则,应使用排序规则,例如

  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
  select '#' collate "POSIX"
   union all
  select 'A' collate "POSIX"
   union all
  select '#Example' collate "POSIX"
order by 1 asc
返回(根据您的情况需要)


似乎,在对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
  select '#' collate "POSIX"
   union all
  select 'A' collate "POSIX"
   union all
  select '#Example' collate "POSIX"
order by 1 asc
返回(注意:DBMS不注意“A”…“E”之前的前缀)

在你的例子中,Postgres实际排序的是

'
'A'
'Example'

如果在字符串的中间放置<代码> '>代码>代码,行为将是相同的:

返回(
被忽略,因此实际比较了
'AB',AC',AD'
'AE'

要更改比较规则,应使用排序规则,例如

  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
  select '#' collate "POSIX"
   union all
  select 'A' collate "POSIX"
   union all
  select '#Example' collate "POSIX"
order by 1 asc
返回(根据您的情况需要)

文本的排序行为(包括
char
varchar
以及
text
类型)取决于区域设置的当前排序规则

见前面密切相关的问题:

如果您想按ASCII值进行过于简单的排序,而不是按照本地语言规则进行适当本地化的排序

或全局更改数据库排序规则(需要转储和重新加载,或完全重新索引)。在Fedora 19 Linux系统上,我得到以下结果:

#
A
#Example
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排序处理。

文本的排序行为(包括
char
varchar
以及
text
类型)取决于您所在地区的当前排序规则

见前面密切相关的问题:

如果您想按ASCII值进行过于简单的排序,而不是按照本地语言规则进行适当本地化的排序

或全局更改数据库排序规则(需要转储和重新加载,或完全重新索引)。在Fedora 19 Linux系统上,我得到以下结果:

#
A
#Example
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排序处理。

这里有一个SQL FIDLE:。@GordonLinoff:我在SQL Server 2008 R2上测试了它,#示例如预期在第二行
title
列的数据类型是什么?哇,在Gordon的SQLFIDLE中添加了
desc
,生成了“#示例”,“A”,“#”Oracle 11.2返回了相同的错误顺序这是一个SQL FIDLE:。@GordonLinoff:我在SQL Server 2008 R2上测试了它,#示例如预期在第二行
title
列的数据类型是什么?哇,在Gordon的SQLFIDLE中添加
desc
,会产生“#示例”,“A”,“#”Oracle 11.2返回相同的错误顺序,但这会先用哈希对“#A”、“C”、“B”进行排序。@Glenn:是的,“#”被忽略,而“#A”、“C”、“B”按其应为“#A”、“B”、“C”的顺序排序(因为“A”<“B”<“C”)这取决于数据库的排序规则。当我在本地数据库上运行您的语句(使用UTF8和德语排序)时,会按以下顺序得到结果:
、\C、\D、*、*B、*E、a
,但这会先用哈希对“\a”、“C”、“B”进行排序。@Glenn:是的,\35;“忽略”和“\a”、“C”、“B”按其应为“\a”、“B”、“C”的顺序排序这取决于数据库的排序规则。当我在本地数据库上运行您的语句(使用UTF8和德语排序规则)时,得到的结果顺序如下:
、\C、\D、*、*B、*E、a