Sql 除法商的四舍五入?

Sql 除法商的四舍五入?,sql,postgresql,rounding,Sql,Postgresql,Rounding,我试图在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 cu

我试图在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
查询的其余部分将包含多个日期,因此其中的日期应该是必需的

它给出的错误是:

错误:函数舍入(双精度,整数)不存在


这是在PostgreSQL中尝试的。

我重新格式化了您的示例代码,以尝试更轻松地理解它:

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
数据类型


因此,表达式的结果是一个
双精度
值,而不是一个
数值
值,因此出现了您观察到的错误。

我重新格式化了示例代码,以便更容易地理解它:

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
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;
问题是,您正在将除法运算的分子强制转换为
float
数据类型

因此表达式的结果是一个
双精度
值,而不是一个
数值
值,因此您观察到了错误

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()
    。仅适用于数值型

  • 将浮点数除以
    数值
    得到
    双精度
    float8
    )。测试:

  • 在计算结束时循环一次。这更快更准确

  • 切勿使用
    date
    作为列名。它在标准SQL中是保留字,在Postgres中是基类型

  • 最好在代码中使用in-date文本。这项工作与设置和区域设置无关,而您的本地格式会因不同的设置而中断

如果不是您提到的查询的
其余部分
,则可以进一步简化:

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;
最后,它还使用除数上的
null()

  • Postgres中没有为浮点类型添加精度修饰符的函数
    round()
    。仅适用于数值型

  • 将浮点数除以
    数值
    得到
    双精度
    float8
    )。测试:

  • 在计算结束时循环一次。这更快更准确

  • 切勿使用
    date
    作为列名。它在标准SQL中是保留字,在Postgres中是基类型

  • 最好在代码中使用in-date文本。这项工作与设置和区域设置无关,而您的本地格式会因不同的设置而中断

  • 如果不是您提到的查询的
    其余部分
    ,则可以进一步简化:

    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除法”异常。

    看起来应该可以工作!您是否尝试强制转换而不是::numeric,例如:强制转换(…作为numeric)?此外,您可以尝试将“amount”合并为0或其他值(以防返回空值)(例如,coalesce(amount,0::expectedtype)),因为它现在正在工作,但唯一的问题是它没有取整它。小数点后仍然有14个数字,因为四舍五入必须在除法之后。不在单个分子和分母上<代码>四舍五入(四舍五入)(当账号为'2999'且日期介于'1/1/14'和当前日期之间时,则金额结束)::数字,4)::浮动/四舍五入(总和(当账号为'3989'且日期介于'1/1/14'和当前日期之间时,则金额结束时):数字,4::数字,4)我认为本质上你的说法是22.0000到4,然后7.000到4,然后将这两个数字分开……3.1428571。。。但是不要四舍五入。哦,我没有意识到问题是数字没有四舍五入,我以为它收到了错误消息。是的,事实上,如果你想得到四舍五入(@xQbert)的结果,你需要在round()/round()周围再加一个“round”。好了,现在我得到了有问题的错误。我会在这个问题上加上另一轮。错误(如前所述)是函数舍入(双精度,整数)不存在,看起来应该可以工作!您是否尝试强制转换而不是::numeric,例如:强制转换(…作为numeric)?此外,您可以尝试将“amount”合并为0或其他值(以防返回空值)(例如,coalesce(amount,0::expectedtype)),因为它现在正在工作,但唯一的问题是它没有取整它。小数点后仍然有14个数字,因为四舍五入必须在除法之后。不在单个分子和分母上<代码>四舍五入(四舍五入)(当账号为'2999'且日期介于'1/1/14'和当前日期之间时,则金额结束)::数字,4)::浮动/四舍五入(总和(当账号为'3989'且日期介于'1/1/14'和当前日期之间时,则金额结束时):数字,4::数字,4)我认为本质上你的说法是22.0000到4,然后7.000到4,然后将这两个数字分开……3.1428571。。。但是不要四舍五入。哦,我没有意识到问题是数字没有四舍五入,我以为它收到了错误消息。是的,事实上,如果你想得到四舍五入(@xQbert)的结果,你需要在round()/round()周围再加一个“round”。好了,现在我得到了有问题的错误。我会在这个问题上加上另一轮。错误(如前所述)是函数舍入(双精度,整数)不存在