这是在sql中强制转换、舍入和平均对象的正确方法吗?

mxg2im7a  于 2021-07-29  发布在  Java
关注(0)|答案(2)|浏览(283)

问题
如何使用 avg 以及 round 在postgresql中提供小数点?
我需要什么函数将字符串转换成十进制数?
使用的函数
第一功能

AVG(ratings.dating) AS scent_avg

第一个错误

Error: expected { scents_id: 1, scent_avg: 4.5 } response body, got { scents_id: 1, scent_avg: '4.5000000000000000' }

第二功能

ROUND(AVG(ratings.rating), 1) AS scent_avg

第二个错误

Error: expected { scents_id: 1, scent_avg: 4.5 } response body, got { scents_id: 1, scent_avg: '4.5' }

第三功能
什么函数用于将字符串转换为数字?
编辑
看来我精神失常了。sticky bit阐明int没有小数!我从原来的帖子中删除了int位。

raogr8fs

raogr8fs1#

格式化字符串

使用 to_char() 要获得没有不重要的零(或填充空格)的格式化字符串,请按您的注解“四舍五入到小数点后十位”:

SELECT to_char(round(avg(ratings.rating), 10), 'FM999999999990.9999999999')

注意那个 0 . 在任何情况下,你通常都想要那个职位。喜欢 0.3 . 添加尽可能多的 9 因为你想允许数字。手册: 0 指定将始终打印的数字位置,即使它包含前导/尾随零。 9 还指定一个数字位置,但如果它是前导零,则将被空格替换,而如果它是尾随零,并且指定了填充模式,则将被删除。
关于 FM 前缀:
填充模式(抑制前导零和填充空格)

无不重要尾随零的数值

投给 double precision ( float8 )获取一个没有不重要的尾随零的数值。演员把无关紧要的零修剪掉。通常,转换为浮点数会导致角点舍入错误。
我首先提出了更复杂的解决方案,但因为你只对精度高达小数点后十位和 float8 精确到15个小数位数,此问题不适用。手册:
在所有当前支持的平台上 real 类型的范围约为1e-37到1e+37,精度至少为6位小数。这个 double precision 类型的范围约为1e-307到1e+308,精度至少为15位。值太大或太小都会导致错误。如果输入数字的精度太高,可能会发生舍入。太接近于零的数字如果不能表示为不同于零,则会导致下溢错误。
所以只要:

SELECT round(avg(ratings.rating), 10)::float8

请注意,我们在舍入之后进行铸造,作为 round() 接受小数位数只适用于 numeric (由于浮点数内部存储的不精确性)。
在postgres中,你不会太担心后面的零。手册:
数值是物理存储的,没有任何额外的前导或尾随零。因此,列的声明精度和比例是最大值,而不是固定的分配(从这个意义上说,数字类型更类似于 varchar(n) 而不是 char(n) )实际的存储需求是四位十进制数字的每组两个字节,加上三到八个字节的开销。
请参见:
postgresql将尾随零添加到数字
在postgres内部,平等是正确建立的:

SELECT numeric '4.50000000' = numeric '4.5'  -- true
SELECT jsonb '{"scents_id": 4.5}' = jsonb '{"scents_id": 4.5000}'  -- true

抛出错误的客户机似乎比较了文本表示,这是非常不正确的。所以你可能需要像你的客户期望的那样格式化。。。

5sxhfpxr

5sxhfpxr2#

在大多数数据库中,这应该起到以下作用:

cast(avg(ratings.ratio * 1.0) as decimal(4, 1))

我看不到有什么圆的。 4.5 是平均值 4 以及 5 从数学上讲。

相关问题