PostgreSQL错误排序
我使用PostgreSQL 9.3.3,我有一个表,其中一列名为title(字符变化(50)) 当我执行以下查询时: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'), ('
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
类型)取决于区域设置的当前排序规则
见前面密切相关的问题:
#
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
类型)取决于您所在地区的当前排序规则
见前面密切相关的问题:
#
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