我有一个使用da_DK.utf8语言环境创建的PostgreSQL 8.4数据库。
dbname=> show lc_collate;
lc_collate
------------
da_DK.utf8
(1 row)
当我从一个表格中选择一个我在一个字符变化列上订购的东西时,我得到一个奇怪的行为IMO。在排序结果时,PostgreSQL会忽略前缀值的破折号,例如:
select name from mytable order by name asc;
可能会返回类似
的内容 name
----------------
Ad...
Ae...
Ag...
- Ak....
At....
短划线前缀似乎被忽略了。
我可以通过在订购时将列转换为latin1来解决此问题:
select name from mytable order by convert_to(name, 'latin1') asc;
我得到了预期的结果:
name
----------------
- Ak....
Ad...
Ae...
Ag...
At....
为什么默认情况下会忽略短划线前缀?可以改变这种行为吗?
答案 0 :(得分:3)
这是因为da_DK.utf8
语言环境以这种方式定义它。 Linux语言环境感知实用程序,例如sort
也可以这样工作。
如果convert_to(name, 'latin1')
找到的字符不是拉丁语1字符集,例如€
,那么order by convert_to(name, 'SQL_ASCII')
会中断,所以这不是一个好的解决方法。
您可以使用order by
(
ascii(name) between ascii('a') and ascii('z')
or ascii(name) between ascii('A') and ascii('Z')
or ascii(name)>127
),
name;
,它将忽略区域设置定义的排序,只使用字节值。
丑陋的黑客编辑:
{{1}}
这将首先排序以ASCII非字母开头的任何内容。这非常难看,因为在字符串中进一步排序会表现得很奇怪,但它对你来说已经足够了。
答案 1 :(得分:1)
在我的特定情况下可以使用的解决方法是用感叹号替换破折号。我碰巧知道我永远不会得到感叹号,它会在任何字母或数字之前排序。
select name from mytable order by translate(name, '-', '!') asc
它肯定会影响性能,所以我可能会考虑创建一个专门的排序列,但我真的不喜欢它......
答案 2 :(得分:0)
我不知道荷兰语的排序规则怎么样,但是对于波兰语中的特殊字符,如空格,短划线等,在大多数词典的排序中都没有“计算”。一些好的排序例程也会这样做并忽略这些特殊字符。可能在荷兰语中有类似的规则,这个规则是由Ubuntu语言环境感知排序函数实现的。