Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将额外参数传递给PostgreSQL聚合最终函数_Sql_Postgresql_Aggregate Functions - Fatal编程技术网

将额外参数传递给PostgreSQL聚合最终函数

将额外参数传递给PostgreSQL聚合最终函数,sql,postgresql,aggregate-functions,Sql,Postgresql,Aggregate Functions,将额外参数传递给PostgreSQL聚合的最终函数以创建状态值的特殊类型的唯一方法是什么 e、 g: 然后将此类型用作状态变量,以便第三个参数(文本)最终到达最终函数 为什么聚合不能将额外的参数传递给最终函数本身?实施原因是什么 例如,我们可以通过以下方法轻松构建聚合: SELECT ST_MyAgg(accum_number, 'COMPUTE_METHOD') FROM blablabla 谢谢您必须重写最终函数本身,在这种情况下,您还可以编写一组新的聚合函数,每个可能的计算方法一个。如果

将额外参数传递给PostgreSQL聚合的最终函数以创建状态值的特殊类型的唯一方法是什么

e、 g:

然后将此类型用作状态变量,以便第三个参数(文本)最终到达最终函数

为什么聚合不能将额外的参数传递给最终函数本身?实施原因是什么

例如,我们可以通过以下方法轻松构建聚合:

SELECT ST_MyAgg(accum_number, 'COMPUTE_METHOD') FROM blablabla

谢谢

您必须重写最终函数本身,在这种情况下,您还可以编写一组新的聚合函数,每个可能的
计算方法一个。如果
COMPUTE\u方法
是数据值或由数据值隐含,则可以使用CASE语句选择适当的聚合方法。或者,您可能希望创建一个自定义复合类型,其中包含
accum\u number
COMPUTE\u METHOD
字段,并编写一个使用此新数据类型的新聚合函数。

您可以使用多个参数定义聚合

我不知道这是否解决了您的问题,但您可以这样使用它:

CREATE OR REPLACE FUNCTION myaggsfunc(integer, integer, text) RETURNS integer
   IMMUTABLE STRICT LANGUAGE sql AS
$f$
   SELECT CASE $3
           WHEN '+' THEN $1 + $2
           WHEN '*' THEN $1 * $2
           ELSE NULL
        END
$f$;

CREATE AGGREGATE myagg(integer, text) (
   SFUNC = myaggsfunc(integer, integer, text),
   STYPE = integer
);
CREATE TABLE mytab
   AS SELECT * FROM generate_series(1, 10) i;

SELECT myagg(i, '+') FROM mytab;

 myagg 
-------
    55
(1 row)

SELECT myagg(i, '*') FROM mytab;

  myagg  
---------
 3628800
(1 row)
它可以这样使用:

CREATE OR REPLACE FUNCTION myaggsfunc(integer, integer, text) RETURNS integer
   IMMUTABLE STRICT LANGUAGE sql AS
$f$
   SELECT CASE $3
           WHEN '+' THEN $1 + $2
           WHEN '*' THEN $1 * $2
           ELSE NULL
        END
$f$;

CREATE AGGREGATE myagg(integer, text) (
   SFUNC = myaggsfunc(integer, integer, text),
   STYPE = integer
);
CREATE TABLE mytab
   AS SELECT * FROM generate_series(1, 10) i;

SELECT myagg(i, '+') FROM mytab;

 myagg 
-------
    55
(1 row)

SELECT myagg(i, '*') FROM mytab;

  myagg  
---------
 3628800
(1 row)

我通过创建一个自定义聚合函数解决了一个类似的问题,该函数一次执行所有操作,并将它们的状态存储在一个数组中

CREATE AGGREGATE myagg(integer)
(
    INITCOND = '{ 0, 1 }',
    STYPE = integer[],
    SFUNC = myaggsfunc
);
以及:

然后执行另一个函数,该函数根据第二个参数选择一个结果:

CREATE OR REPLACE FUNCTION myagg_pick(agg_state integer[], agg_fn character varying)
RETURNS integer IMMUTABLE STRICT LANGUAGE 'plpgsql' AS $$
BEGIN
    CASE agg_fn
        WHEN '+' THEN RETURN agg_state[1];
        WHEN '*' THEN RETURN agg_state[2];
        ELSE RETURN 0;
    END CASE;
END;
$$;
用法:

SELECT myagg_pick(myagg("accum_number"), 'COMPUTE_METHOD') FROM "mytable" GROUP BY ...

明显的缺点是执行所有函数而不是一个函数的开销。但是,在处理简单的操作(如加法、乘法等)时,大多数情况下都是可以接受的。

重点是“如何将附加参数传递给最终函数?”。将它们传递给state函数很容易。没有办法做到这一点,您必须创建自己的类型。我的回答是从你的例子中得到启发的。你想解决的问题是什么?也许有一种比为final函数添加额外参数更简单的方法。为什么PostgreSQL不允许为final函数添加额外参数?有很多有用的情况。。。这个决定的基础是什么?这是不必要的。正如我的回答所解释的,您可以使用现有的功能来实现它。您可以更直接地处理final函数的参数,方法是使用状态的复合类型,并将所需的参数作为该状态的元素之一。“COMPUTE_METHOD”是一个文本参数,指定final函数中必须如何计算最终结果。问题是将此参数传递给最终函数。显然,这是不可能的,除非构建一个包含此文本参数的新类型,该参数过于复杂。