私はRuby gem 'sequel'を通してPostgreSQLを使っています。
小数点以下2桁に丸めようとしています。
これが私のコードです:
SELECT ROUND(AVG(some_column),2)
FROM table
次のようなエラーが表示されます。
PG::Error: ERROR: function round(double precision, integer) does
not exist (Sequel::DatabaseError)
次のコードを実行してもエラーにはなりません。
SELECT ROUND(AVG(some_column))
FROM table
誰かが私が間違っていることを知っていますか?
PostgreSQLはround(double precision, integer)
を定義していません。 @Catcallがコメントで説明している理由で、精度を取るroundのバージョンはnumeric
でのみ利用可能です。
regress=> SELECT round( float8 '3.1415927', 2 );
ERROR: function round(double precision, integer) does not exist
regress=> \df *round*
List of functions
Schema | Name | Result data type | Argument data types | Type
------------+--------+------------------+---------------------+--------
pg_catalog | dround | double precision | double precision | normal
pg_catalog | round | double precision | double precision | normal
pg_catalog | round | numeric | numeric | normal
pg_catalog | round | numeric | numeric, integer | normal
(4 rows)
regress=> SELECT round( CAST(float8 '3.1415927' as numeric), 2);
round
-------
3.14
(1 row)
(上記では、float8
はdouble precision
の単なる省略形のエイリアスです。PostgreSQLが出力でそれを拡張していることがわかります)。
2引数形式のnumeric
を使用するには、値をround
に丸めるようにキャストする必要があります。 round(val::numeric,2)
のように、省略形のキャストには::numeric
を追加するだけです。
ユーザーへの表示用にフォーマットしている場合は、round
を使用しないでください。 to_char
(マニュアルの データ型フォーマット関数 を参照)を使用すると、フォーマットを指定でき、クライアント言語がtext
の値を使用した場合の影響を受けないnumeric
の結果が得られます。例えば:
regress=> SELECT to_char(float8 '3.1415927', 'FM999999999.00');
to_char
---------------
3.14
(1 row)
to_char
はフォーマットの一部としてあなたのために数字を丸めます。 FM
という接頭辞は、先頭のスペースを埋め込む必要がないことをto_char
に伝えます。
キャストのための古い構文も試してください。
SELECT ROUND(AVG(some_column)::numeric,2)
FROM table;
postgreSQLのどのバージョンでも動作します。
いくつかのPostgreSQL関数にはオーバーロードの欠如があります、なぜ(???):私は「それは欠如である」と思います(!)、しかし@ CraigRinger、@ Catcall、そしてPostgreSQLチームは "pgの歴史的根拠"について同意します。
シモンズ:四捨五入についてのもう一つのポイントは精度、チェック @ IanKenney's answer です。
オーバーロード ROUND関数で、
CREATE FUNCTION ROUND(float,int) RETURNS NUMERIC AS $$
SELECT ROUND($1::numeric,$2);
$$ language SQL IMMUTABLE;
これであなたの命令はうまくいくでしょう、試してみてください(関数作成後)
SELECT round(1/3.,4); -- 0.3333 numeric
しかし、それはNUMERIC型を返します...最初のcommom-usageオーバーロードを保持するために、TEXTパラメータが提供されたときにFLOAT型を返すことができます。
CREATE FUNCTION ROUND(float, text, int DEFAULT 0)
RETURNS FLOAT AS $$
SELECT CASE WHEN $2='dec'
THEN ROUND($1::numeric,$3)::float
-- ... WHEN $2='hex' THEN ... WHEN $2='bin' THEN... complete!
ELSE 'NaN'::float -- like an error message
END;
$$ language SQL IMMUTABLE;
やってみる
SELECT round(1/3.,'dec',4); -- 0.3333 float!
SELECT round(2.8+1/3.,'dec',1); -- 3.1 float!
SELECT round(2.8+1/3.,'dec'::text); -- need to cast string? pg bug
PS:オーバーロード後に\df round
をチェックすると、
スキーマ|名前|結果データ型引数のデータ型 ------------ + ------- + ------------------ + - -------------------------- myschema |ラウンド|倍精度|倍精度、テキスト、整数 ラウンド|数値|倍精度、整数 pg_catalog |ラウンド|倍精度|倍精度 pg_catalog |ラウンド|数値|数値 pg_catalog |ラウンド|数値|数値、整数
pg_catalog
関数はデフォルトのものです。 組み込み数学関数のマニュアル を参照してください。
これを試してみてください。
SELECT to_char (2/3::float, 'FM999999990.00');
-- RESULT: 0.67
または単に:
SELECT round (2/3::DECIMAL, 2)::TEXT
-- RESULT: 0.67
Bryan's レスポンスによると、これを実行してクエリ内の小数部を制限することができます。 km/hからm/sに変換してグラフに表示しましたが、グラフにしたときは奇妙に見えました。代わりにクエリで計算をするときは、きれいに見えます。これはpostgresql 9.5.1にあります。
select date,(wind_speed/3.6)::numeric(7,1) from readings;
エラー:関数round(倍精度、整数)が存在しません
Solution:型キャストを追加する必要があります。それでうまくいくでしょう
例:round(extract(second from job_end_time_t)::integer,0)
あなたは以下の機能を使用することができます
SELECT TRUNC(14.568,2);
結果は次のようになります。
14.56
変数を希望の型にキャストすることもできます。
SELECT TRUNC(YOUR_VAR::numeric,2)