PostgreSQLのround(numeric、integer)関数は、切り上げのみを行います。
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;
数値をキャストして正規表現を使用する必要があります...それが(おそらく)パフォーマンスを殺すものです。
ご存知のとおり、これが必要なのは、2つの異なる列(2つの異なるテーブル)に格納されているが、数値データ型が異なる数値を比較する必要があるためです。1つはdoubleで、もう1つはrealです。問題は、実際のデータ型の列に挿入するときに、PostgreSQLが数学関数を介してそのようなオプションを提供しないのに、ROUNDHALFDOWNを実行することです。
編集:
関数は実際にバグがあります。動作中の関数のパフォーマンスを改善する試みとしての最初の迅速な書き直しでしたが、非常に低速でした。
動作は次のように一致する必要があります。
IF
丸めから延期される小数桁は切り上げ<=5 => trunc
ELSE
られます。
いくつかの例:
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のラウンド関数は次のようになります。
select round(cast (41.002555 as numeric),3) -- 41.003