PostgreSQL中的字母数字排序

时间:2017-04-03 02:37:28

标签: postgresql sorting natural-sort bytea

我在Postgres 9.6中有一个character varying列的表:

id | column 
------------
1  |IR ABC-1
2  |IR ABC-2
3  |IR ABC-10

我看到一些解决方案将列标记为bytea

select * from table order by column::bytea.

但它总是导致:

id | column 
------------
1  |IR ABC-1
2  |IR ABC-10
3  |IR ABC-2

我不知道为什么' 10'总是在' 2'之前。如何排序此表,假设排序的基础是字符串的最后一个整数,无论​​该数字前面的字符是什么。

2 个答案:

答案 0 :(得分:1)

排序字符数据类型的一个可能问题是collation rules适用(除非您使用区域设置" C"(它只是默认按字节值排序字符)。应用排序规则可能在任何情况下,它都会使排序变得更加昂贵。如果你想在没有整理规则的情况下进行排序,请不要使用bytea,而是使用COLLATE "C"代替:

SELECT * FROM table ORDER BY column COLLATE "C";

However,这还没有解决你提到的字符串中的数字问题。您必须拆分字符串并将数字部分排序为数字。

SELECT *
FROM   table
ORDER  BY split_part(column, '-', 2)::numeric;

或者,如果您的所有号码都适合bigint甚至integer,请改用它。

我忽略了主要部分,因为你写道:

  

...排序的基础是字符串的最后一个整数,无论​​该数字前面的字符是什么。

相关:

通常,最好将字符串的不同部分保存在单独的列中作为适当的相应数据类型,以避免任何此类混淆。

如果所有列的前导字符串相同,请考虑删除冗余噪声。您始终可以使用VIEW添加字符串进行显示。

答案 1 :(得分:0)

在评论中分割并转换整数部分

select *
from
    table
    cross join lateral
    regexp_split_to_array(column, '-') r (a)
order by a[1], a[2]::integer