double precision
入力を( float8
) からにキャストするか、集計numeric
のフレーバーを定義します。double precision
あなたの集計はうまくいきます:
regress=> CREATE AGGREGATE nmul(numeric)
regress-> (
regress(> sfunc = numeric_mul,
regress(> stype = numeric
regress(> );
regress=> SELECT nmul(x) FROM generate_series(1,100) x;
nmul
----------------------------------------------------------------------------------------------------------------------------------------------------------------
93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
(1 row)
問題はあなたのクエリです:
regress=> SELECT nmul(x::float8) FROM generate_series(1,100) x;
ERROR: function nmul(double precision) does not exist
LINE 1: SELECT nmul(x::float8) FROM generate_series(1,100) x;
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
float8
集計のバージョンを定義できます(float8
は の同義語ですdouble precision
)。
regress=> CREATE AGGREGATE nmul(double precision)
(
sfunc = float8mul,
stype = float8
);
regress=> SELECT nmul(x::float8) FROM generate_series(1,100) x;
fmul
-----------------------
9.33262154439441e+157
(1 row)
numeric
または、値の完全な精度を保持したい場合は、集計の前にキャストします。たとえば、次のようになります。
CAST(nmul(CAST("cote" AS numeric)) AS INT)
または PostgreSQL 固有の短縮キャスト:
nmul("cote"::numeric)::integer
integer
これらの製品集計を使用している場合、すぐにオーバーフローすることに注意してください。
regress=> SELECT nmul(x)::integer FROM generate_series(1,12) x;
nmul
-----------
479001600
(1 row)
regress=> SELECT nmul(x)::integer FROM generate_series(1,13) x;
ERROR: integer out of range
regress=>
numeric
とにかく使い続けたいと思うでしょう。