postgresql Postgres使用不同的元素数据类型对数据进行排序

q9yhzks0  于 2023-08-04  发布在  PostgreSQL
关注(0)|答案(1)|浏览(155)

我有一个带有Char数据类型字段的postgres模型。在这种Char数据类型中,我需要基本上注册数字,但我不能将它们记录为Integer。
如果我尝试使用默认数据类型(Char)来排序数据,我会得到:

82
821
8219 (correct position as Char, but wrong position as an Integer)
822
823
824
825
826
827 
828
829

字符串
我需要将这个char数据作为一个Integer元素排序,这样我就可以将值“8219”放到列表底部的正确位置。
我尝试使用ORDER_BYINT(field_name,但没有成功。
我尝试使用ORDER_BY INT(field_name),但没有成功。

axr492tv

axr492tv1#

如果我创建这个模式

create table mytable(
    something char(12)
);

insert into mytable(something)
values
('82'),
('821'),
('8219'),
('822'),
('823'),
('824'),
('825'),
('826'),
('827 '),
('828'),
('829');

字符串
然后运行这个查询:

select something
from mytable
order by something::integer;


然后我得到了正确的结果:
x1c 0d1x的数据
小提琴:http://sqlfiddle.com/#!17/794bf/1
其思想是,您可以在order by子句中将字段转换为integer,因此将值作为整数进行比较。这种行为的原因是,如果比较字符串,那么“12”比“9”“小”,因为字符串是通过每个字符来比较的,无论哪里有差异,哪个字符大于另一个字符决定比较。如果所有字符比较都产生相同的字符,则较长的字符串是“更大”。这就是为什么你想将它们作为整数进行比较。
现在,您还应该问问自己,将该字段的数据存储为char而不是整数是否有意义。如果没有这种原因,则可以更改表并更改字段的类型。
编辑
Belayer提出了一个在存储非数字字符时可能发生的问题。因此,我更新了小提琴,现在可以在http://sqlfiddle.com/#找到!17/bc2c4a/5
首先,我添加了一些其他的值:

create table mytable(
    something char(12)
);

insert into mytable(something)
values
('82'),
('821'),
('8219'),
('822'),
('823'),
('824'),
('825'),
('826'),
('827 '),
('828'),
('829'),
('not a number'),
('3.14'),
(null),
(-3),
(-3.14);


我们有一个非数值('not a number'),一个数值浮点('3.14'),null和一些负数(分别为'-3''-3.14')。
这就是我们如何将它们分类为float:

select something
from mytable
order by case when textregexeq(something,'^(-)?[[:digit:]]+(\.[[:digit:]]+)?$') then something::float else null end;


正则表达式指定它可以以-开头,然后以任意数位继续,并且可以在至少一个数字后面加上一个点。在排序时,对应于该正则表达式的任何值都将具有其float转换,其他值将具有null
如果我们希望它们按整数排序:

select something
from mytable
order by case when textregexeq(something,'^(-)?[[:digit:]]+?$') then something::integer else null end;


请注意,有两个区别。首先,我们从正则表达式中删除了“可能以一个点结尾,至少有一个数字”部分,其次,我们将值转换为整数。
在这两种情况下,我们使用case-when方法,也就是说,我们检查值是否可以转换为我们打算在比较中使用的类型,如果可以,我们将在排序过程中使用它的转换作为它的代表。否则,我们默认它为某个东西,我使用null作为默认值,但如果需要,可以更改为其他东西。

相关问题