我试图在select语句中划分两列,然后将商舍入到4位小数。
select round(round(sum(case when acct_no = '2999'
and date between '1/1/14' and current_date then amount end)::numeric, 4)::float
/ round(sum(case when acct_no = '3989'
and date between '1/1/14' and current_date then amount end)::numeric, 4)::numeric, 4) column
from table
查询的其余部分将包含多个日期,因此其中的日期应该是必要的。
它给出的错误:
错误:函数round(双精度,整数)不存在
这是在PostgreSQL中尝试的。
答案 0 :(得分:4)
SELECT round((
sum(CASE WHEN acct_no = '2999'
AND thedate between '2014-1-1' AND current_date THEN amount END)
/ sum(CASE WHEN acct_no = '3989'
AND thedate between '2014-1-1' AND current_date THEN amount END)
)::numeric, 4) AS result
FROM tbl;
Postgres中的浮点类型没有添加精度修饰符的函数round()
。仅适用于numeric
,as per documentation。
将浮点数除以numeric
会产生double precision
(float8
)。测试:
SELECT 5::float/3::numeric -- result is double precision
在计算结束时将舍入一次。这更快,更准确。
切勿使用date
作为列名。它是标准SQL中的保留字和Postgres中的基本类型。
最好在代码中使用日期文字中的recommended ISO 8601 date format。无论设置和区域设置如何,这都有效,而本地格式会因不同的设置而中断。
如果不是您提到的rest of the query
,则可以进一步简化:
SELECT round(( sum(CASE WHEN acct_no = '2999' THEN amount END)
/ NULLIF(sum(CASE WHEN acct_no = '3989' THEN amount END), 0)
)::numeric, 4) AS result
FROM tbl
WHERE thedate between '2014-1-1'::date AND current_date;
最后,这也使用除数上的NULLIF()
来捕获“除以0”异常。
答案 1 :(得分:3)
我重新格式化了您的示例代码,以便更轻松地理解它:
select round(
round(
sum(
case
when acct_no = '2999'
and date between '1/1/14' and current_date then amount
end )::numeric,
4 )::float
/ round(
sum(
case
when acct_no = '3989'
and date between '1/1/14' and current_date then amount
end )::numeric,
4 )::numeric,
4 ) column
from table
问题在于您将分部操作的分子转换为float
数据类型which, because you didn't specify a precision, is equivalent to double precision
。
round(
sum(
case
when acct_no = '2999'
and date between '1/1/14' and current_date then amount
end )::numeric,
4 )::float
/ round(
sum(
case
when acct_no = '3989'
and date between '1/1/14' and current_date then amount
end )::numeric,
4 )::numeric
因此,表达式的结果是double precision
值而不是numeric
值,因此您观察到的错误。