postgresql圆半下来功能
PostgreSQL中的round(数字,整数)函数只会向上舍入:
round(cast (41.0255 as numeric),3) ==> 41.026 由于我们需要一个返回41.025的圆函数(非常令人惊讶)在PostgreSQL中没有这样的函数(我们使用的是9.1.5),我们编写了一个“包装”函数,在第一个版本中它非常天真,粗糙……但由于缺乏对plpgsql中此类问题的本机支持,我们没有找到更好的东西. 代码如下所示.问题是它对我们的目的来说太慢了. 这是代码: CREATE OR REPLACE FUNCTION round_half_down(numeric,integer) RETURNS numeric AS $$ DECLARE arg ALIAS FOR $1; rnd ALIAS FOR $2; tmp1 numeric; res numeric; BEGIN tmp1:=arg; IF cast(tmp1 as varchar) ~ '5$' THEN res:=trunc(arg,rnd); ELSE res:=round(arg,rnd); END IF; RETURN res; END; $$LANGUAGE plpgsql; 我需要转换数值并使用正则表达式…这就是(我猜)杀死表演的东西. 您知道:我们需要这个,因为我们必须比较存储在两个不同列(在两个不同的表上)但具有不同数值数据类型的数字:一个是double,一个是real.问题是当插入真实数据类型列时,PostgreSQL执行ROUND HALF DOWN,而它不通过其数学函数提供这样的选项! 编辑: 行为必须符合以下条件: 一些例子: select round_half_down(cast (41.002555 as numeric),3) -- 41.002 select round_half_down(cast (41.002555 as numeric),4) -- 41.0025 select round_half_down(cast (41.002555 as numeric),5) -- 41.00255 而PostgreSQL中的round函数给出: select round(cast (41.002555 as numeric),3) -- 41.003 解决方法
这应该非常快速和简单: SELECT dp_col,real_col FROM tbl WHERE dp_col::real = real_col 基本上,只需将双精度数转换为实数即可进行比较. 如果这对你不起作用,这个SQL函数应该做一个合适的工作并且工作得更快: CREATE OR REPLACE FUNCTION round_half_down1(numeric,int) RETURNS numeric LANGUAGE sql AS $func$ SELECT CASE WHEN abs($1%0.1^$2) < .6 * 0.1^$2 THEN trunc($1,$2) ELSE round($1,$2) END; $func$ 现在修复了负数,并在评论中输入@sufleR. % .. modulo operator 这是一个可用于基准测试的快速测试: SELECT n -- Total runtime: 36.524 ms,round_half_down1(n,3) -- Total runtime: 70.493 ms,round_down_to_decimal_places(n,3) -- Total runtime: 74.690 ms,round_half_down(n,3) -- Total runtime: 82.191 ms FROM (SELECT random()::numeric AS n FROM generate_series(1,10000)) x WHERE round_down_to_decimal_places(n,3) <> round_half_down1(n,3) 它还演示了@ Parveen的函数和编辑后的版本是如何计算错误的 – 它们不应该在哪里截断(). (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |