Найти SUM и MAX в пользовательской статистической функции - PullRequest
1 голос
/ 13 мая 2019

Я недавно работал с пользовательской агрегатной функцией. В этом пользовательском агрегате первая функция неправильно вычисляет сумму и максимальное значение. Я использую составной тип для возврата суммы и максимального значения.

Я пытался добавить все в массив, но это не эффективный способ работы

CREATE TYPE sum_max_complex AS (sum real, max_v real);

CREATE OR REPLACE FUNCTION calculateSum(sum_max_complex, real) RETURNS sum_max_complex AS $$
DECLARE 
   sumValue real := 0;
   max_v real := $2;
   output sum_max_complex;
BEGIN
    RAISE NOTICE '-------------------';
    RAISE NOTICE 'IL PRIMO VALORE DI INPUT E: % ... %',$1.sum,$1.max_v;
    RAISE NOTICE 'IL SECONDO VALORE DI INPUT E: %',$2;
    IF $2 IS NOT NULL THEN
      sumValue := calculateSumAggregate(sumValue,$2) + sumValue;
    ELSE
      sumValue := sumValue;
    END IF;
    max_v := searchmaximumvalue(max_v,$2);


    output.sum := sumValue;
    output.max_v := max_v;

    RAISE NOTICE '-------------------';
    RAISE NOTICE 'IL VALORE DI OUTPUT SONO: % ... %',output.sum,output.max_v;
    RETURN output;
END;
$$ LANGUAGE plpgsql;

CREATE OR REPLACE FUNCTION addLaplacianNoiseSum(sum_max_complex) RETURNS real AS $$
DECLARE
   epsilon real := 0.005;
   sensivity real := $1.max_v;
   laplaceDistribution real;
BEGIN

   laplaceDistribution := generaterandomvalues(sensivity / (epsilon));

   RETURN  $1.sum + laplaceDistribution;
END;
$$ LANGUAGE plpgsql;

CREATE AGGREGATE SUM_LAPLACE(real)
(
  SFUNC = calculateSum,
  STYPE = sum_max_complex,
  FINALFUNC = addLaplacianNoiseSum
);

В столбце таблицы указаны значения 19,22,22,5,27. Он принимает правильное значение в методе параметра $ 2, в 1-й функции, но не накапливает и не суммирует каждое значение.

1 Ответ

2 голосов
/ 13 мая 2019

Не похоже, что вы когда-либо добавляете к значениям, хранящимся в типе sum_max_complex. Вот упрощенный пример, который показывает примерно, что вы должны сделать. Я не знаю, что делают convertSumAggregate или генерируют случайные значения, поэтому я не смог их воспроизвести.

CREATE TYPE sum_max_complex AS (sum real, max_v real);

CREATE OR REPLACE FUNCTION calculateSum(sum_max_complex, real) RETURNS sum_max_complex AS $$
select ROW(
    $1.sum + coalesce($2, 0),
    greatest($1.max_v, $2)
)::sum_max_complex;
$$ LANGUAGE SQL IMMUTABLE;

CREATE OR REPLACE FUNCTION addLaplacianNoiseSum(sum_max_complex) RETURNS real AS $$
  select $1.sum + ($1.max_v/0.005);
$$ LANGUAGE SQL IMMUTABLE;

CREATE AGGREGATE SUM_LAPLACE(real)
(
  SFUNC = calculateSum,
  STYPE = sum_max_complex,
  FINALFUNC = addLaplacianNoiseSum,
  INITCOND = '(0, 0)'
);

with a as (select a from (values (19), (22), (22.5), (27)) v(a))
select sum_laplace(a) from a;
 sum_laplace
-------------
      5490.5
...