将串联与ORDER BY结合使用

jut*_*tky 9 sql postgresql concatenation collation sql-order-by

我在Postgre(9.1.9)中将连接与顺序结合起来很麻烦.比方说,我有一个带有3个字段的表格边框:

            Table "borders"
    Column     |         Type         | Modifiers 
---------------+----------------------+-----------
 country1      | character varying(4) | not null
 country2      | character varying(4) | not null
 length        | numeric              | 
Run Code Online (Sandbox Code Playgroud)

前两个字段是各国的代码,第三个字段是这些国家之间的边界长度.
主键在前两个字段中定义.

我需要编写一个对整个表具有唯一值的列的选择,此外,应该按降序选择此列.为此,我将关键字段与分隔符字符连接起来,否则两个不同的行可能会给出相同的结果,如(AB,C和A,BC).

所以我运行以下查询:

select  country1||'_'||country2 from borders order by 1;
Run Code Online (Sandbox Code Playgroud)

但是在结果中我看到排序中省略了'_'字符.结果如下:

 ?column? 
----------
 A_CH
 A_CZ
 A_D
 AFG_IR
 AFG_PK
 AFG_TAD
 AFG_TJ
 AFG_TM
 AFG_UZB
 A_FL
 A_H
 A_I
 .
 .
Run Code Online (Sandbox Code Playgroud)

您可以看到结果的排序就像字符串中不存在"_"一样.

如果我使用一个字母(比如'x')作为分隔符 - 订单是正确的.但我必须使用一些未出现在country1和country2字段中的特殊字符,以避免争用.

我应该怎么做,以便在排序过程中考虑'_'字符.


编辑

事实证明,连接与问题无关.问题是订单只是忽略'_'字符.

fog*_*fog 7

只需按两列排序:

SELECT  country1||'_'||country2 FROM borders ORDER BY country1, country2;
Run Code Online (Sandbox Code Playgroud)

除非您使用聚合或窗口,否则即使您没有在SELECT列表中包含它们,PostgreSQL也允许按列排序.

正如在另一个答案中建议的那样,您也可以更改组合列的排序规则,但是,如果可以的话,对普通列进行排序会更快,尤其是如果您有一个索引.


Rom*_*kar 7

select country1 || '_' || country2 collate "C" as a
from borders
order by 1
Run Code Online (Sandbox Code Playgroud)

sql fiddle demo

根据评论中的讨论说明:

1.)只要通过位置参数别名引用子句中的表达式,就COLLATE "C"适用于该ORDER BY子句.如果要重复表达式,则还需要重复该子句,以便相应地影响排序顺序.SELECTORDER BYCOLLATE

sql fiddle demo

2.)在_不影响排序顺序的排序规则中,使用雾的查询更有效,更是如此,因为它使用现有的索引(primary key is defined on the first two fields).
但是,如果_有影响,则需要对组合表达式进行排序:

sql fiddle demo

查询性能(在Postgres 9.2中测试):
sql fiddle demo

手册中的PostgreSQL整理支持.