Прямые аргументы в пользовательских агрегатных функциях PostgreSQL

Я создаю пользовательскую статистическую функцию, которая нуждается в дополнительном параметре. Точнее, это кумулятивный минимум (он же окно), который принимает в качестве второго параметра интервал времени, определяющий окно. Поскольку функция агрегирования работает с моими пользовательскими типами данных, я привел фиктивный пример, который вычисляет среднее значение из n последних значений столбца. Я знаю, что могу решить эту фиктивную проблему в PostgreSQL, но цель этого примера - только подчеркнуть мою проблему.

CREATE FUNCTION lastNavg_transfn(state integer[], next integer, n integer)
    RETURNS integer[] AS $$
    BEGIN
        RETURN array_append(state, next);
    END;
    $$ LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE;

CREATE FUNCTION lastNavg_finalfn(state integer[], n integer)
    RETURNS float AS $$
    DECLARE
        card integer;
        count float;
        sum float;
    BEGIN
        count := 0;
        sum := 0;
        card := array_length(state, 1);
        FOR i IN greatest(1,card-n+1)..card
        LOOP 
            sum := sum + state[i];
            count := count + 1;
        END LOOP;
        RETURN sum/count;
    END;
    $$ LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE;

CREATE AGGREGATE lastNavg(integer, integer) (
    SFUNC = lastNavg_transfn,
    STYPE = integer[],
    INITCOND = '{}',
    FINALFUNC = lastNavg_finalfn,
    PARALLEL = SAFE
);

Я получаю следующую ошибку

ERROR: function lastnavg_finalfn(integer[]) does not exist
SQL state: 42883

Как сказать PostgreSQL, что моей конечной функции также нужен прямой параметр? Я работаю над PostgreSQL 10.1. Я знаю, что согласно документации прямые параметры разрешены только для агрегатов с упорядоченным набором, но мне также понадобится прямой параметр для "обычных" агрегатов.

1 ответ

Вы можете определить агрегат с двумя аргументами и указать дополнительный параметр в качестве постоянного второго аргумента.

SFUNC просто хранит второй аргумент, например, как 0-й элемент STYPE целочисленный массив

FINALFUNC имеет только один аргумент и получает n от 0-го элемента массива.

Если вам нужен второй аргумент, который не является целым числом, определите составной тип и используйте его как STYPE,

Не красиво, но это должно сработать.

Другие вопросы по тегам