4

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

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'之前。如何排序这个表,假设排序的基础是字符串的最后一个整数,不管那个数字之前的字符是什么。

4

2 回答 2

2

对字符数据类型进行排序时,将应用排序规则- 除非您使用按字节值对字符进行排序的语言环境“C”。应用整理规则可能是可取的,也可能是不可取的。在任何情况下,它都会使排序变得更加昂贵。如果您想在没有排序规则的情况下进行排序,请不要强制转换为byteaCOLLATE "C"而是使用:

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

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

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

或者,如果您的所有数字都适合bigint甚至integer,请改用它(更便宜)。

我忽略了前导部分,因为您写道:

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

有关的:

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

如果所有列的前导字符串都相同,请考虑仅删除冗余噪声。您总是可以使用 aVIEW来预先显示一个字符串,或者以便宜的方式即时进行。

于 2017-04-03T12:31:56.780 回答
1

正如在评论中拆分并转换整数部分

select *
from
    table
    cross join lateral
    regexp_split_to_array(column, '-') r (a)
order by a[1], a[2]::integer
于 2017-04-03T12:28:39.627 回答