我尝试在 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)
将您的输入从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
。