我尝试在PostgreSQL中为产品(*)创建聚合。我的行的字段类型是“双精度”。
所以,我尝试了以下代码:
CREATE AGGREGATE nmul(numeric)
(
sfunc = numeric_mul,
stype = numeric
);
当我发起我的查询时,结果为:
ERROR: function nmul(double precision) does not exist
LINE 4: CAST(nmul("cote") AS INT),
谢谢你
我尝试在PostgreSQL中为产品(*)创建聚合。我的行的字段类型是“双精度”。
所以,我尝试了以下代码:
CREATE AGGREGATE nmul(numeric)
(
sfunc = numeric_mul,
stype = numeric
);
ERROR: function nmul(double precision) does not exist
LINE 4: CAST(nmul("cote") AS INT),
谢谢你
我从一个非常聪明的人那里找到了解决方案,他意识到你可以使用对数来实现这一点(归功于他):
select exp(sum(ln(x))) from generate_series(1,5) x;
exp
-----
120
(1 row)
x < 0
,他应该用 z = -x
替换 x
,并将结果乘以 (-1)^x
。 - clapas将输入从 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)
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
。