错误:函数round(double precision, integer)不存在。

54

我正在将一些在MySQL数据库中运行了很长时间的查询迁移到现在已经拥有相同结构的Postgres,但卡在了一个简单的Round函数上,其结果是以下错误信息:

ERROR: function round(double precision, integer) does not exist

无法工作的选择部分:

round(floor(pools.available_capacity_in_kb/1024/1024/1024*100)/100,2) as free,

pools.available_capacity_in_kb在数据库中以BIGINT方式存储(Postgres 10.9)

5个回答

64
我在地理坐标方面遇到了同样的问题。经度是从开放街图数据中以双精度形式给出的,需要一个四舍五入的值。
我的解决方案很好用:
select ROUND(CAST(longitude AS numeric),2) from my_points; 

1
当我在db-fiddle中使用Postgres 9.6时遇到问题,这个解决方案对我有效。 - thedatadavis

38
除了使用类型CAST语法外,您还可以使用以下语法将一个类型的值转换为另一个类型(cast :: operator):
select ROUND(value::numeric, 2) from table_x; 

请注意,使用强制转换运算符(::)的强制转换语法是特定于PostgreSQL的,不符合SQL标准。

我在 round 函数的第一个参数中使用了一个表达式,该表达式返回“双精度”值。经过很多努力,我最终通过将表达式括在括号内并将结果强制转换为数值来解决了这个问题。感谢这个答案。 - Shantilal Suthar

15

问题的核心在于其他地方。当pools.available_capacity_in_kb/1024/1024/1024*100)/100两边都是int,bigint值时,PostgreSQL会对整数和大整数使用长除法。因此,结果是bigint。可能这不是您期望的结果。

postgres=# \df round
                          List of functions
+------------+-------+------------------+---------------------+------+
|   Schema   | Name  | Result data type | Argument data types | Type |
+------------+-------+------------------+---------------------+------+
| pg_catalog | round | double precision | double precision    | func |
| pg_catalog | round | numeric          | numeric             | func |
| pg_catalog | round | numeric          | numeric, integer    | func |
+------------+-------+------------------+---------------------+------+
(3 rows)

对于bigint类型,不存在任何round函数(因为这没有任何意义)。 请尝试使用浮点数除法来解决问题。

pools.available_capacity_in_kb/1024/1024/1024*100)/100.0

现在,结果将是数值,并且函数 round(数值, int) 存在 - 所以它应该能正常工作。


函数序列"round(floor( ...)"是不必要的,而且也没有意义。floor函数返回"小于或等于参数的最大整数",你不能对整数进行四舍五入 - 至少没有不使用UDF的情况下。 - Belayer
非常感谢您快速响应,Pavel。您是正确的 - round 函数在 bigint 上不起作用。我将数据类型更改为 numeric 并且效果很好。round(floor(pools.available_capacity_in_kb::numeric/1024/1024/1024*100)/100,2) as free. - radek lopatecki
@radeklopatecki 所以请关闭此任务。 - Pavel Stehule
有没有SQL等价于\df的命令? - Rafs
1
@Rafs - select oid :: regprocedure from pg_proc where proname like '%round%'; - Pavel Stehule

3
您也可以使用以下语法。
select round((value::Decimal),2) from table_name;

请注意,使用强制转换运算符(::)的类型转换语法是PostgreSQL特有的,不符合SQL标准。

0
在我的情况下,我尝试使用AVG()聚合的列被返回为一个Set(请看错误信息:"ERROR: function avg(double precision[]) does not exist Hint: No function matches the given name and argument types. You might need to add explicit type casts")。
所以,在我的情况下,解决方案是使用子查询并使用Unnest()函数,像这样:
Select avg(unnested_field) from
( 
      Select unnest(field) as unnested_field
      From my_table
) as Subquery

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接