Multi-parameter aggregates.

Поиск
Список
Период
Сортировка
От Berend Tober
Тема Multi-parameter aggregates.
Дата
Msg-id 4381EFCA.2030708@seaworthysys.com
обсуждение исходный текст
Ответы Re: Multi-parameter aggregates.  (Joe Conway <mail@joeconway.com>)
Re: Multi-parameter aggregates.  (Michael Fuhr <mike@fuhr.org>)
Re: Multi-parameter aggregates.  (Tom Lane <tgl@sss.pgh.pa.us>)
Список pgsql-general
I'm interested in defining a covariance aggregate function. (As a
refresher, remember that covariance is a little bit like variance, but
is between two variables:

cov(X,Y)    =  <XY> - <X><Y>,

where the angular brackets in this case denote taking the averag.
Variance is a special case when X and Y are the same.)

But the whole user-defined aggregate thing is tough to get a handle on.
I'm not even sure if the direction I'm heading in below will actually
work, but as far as I got, I'm stuck on not knowing how to define a
aggregate that takes more that one variable as its argument, so its use
in SQL would look like, e.g.,

SELECT company, COVAR(year, sales) FROM annual_sales GROUP BY company;

Here is what I tried, and I'm wondering if the team here can help me
make this work (or tell me that the whole approach makes no sense,
etc.). All the DDL executes without syntactical errors until the last
function definition, and the problem is with the "  BASETYPE=numeric"
line, i.e., "ERROR:  AggregateCreate: function
covariance_accum(numeric[], numeric) does not exist"

CREATE TYPE public._covariance AS
    (n integer, x numeric, y numeric, xy numeric);


CREATE OR REPLACE FUNCTION public.covariance_accum(_covariance, numeric,
numeric)
    RETURNS _covariance AS '
    BEGIN
    _covariance.n := _covariance.n+1;
    _covariance.x := _covariance.x+$2;
    _covariance.y := _covariance.x+$3;
    _covariance.xy:= _covariance.xy+($1*$2);
    END;
    'LANGUAGE 'plpgsql' IMMUTABLE STRICT;
GRANT EXECUTE ON FUNCTION public.covariance_accum(_covariance, numeric,
numeric) TO public;
COMMENT ON FUNCTION public.covariance_accum(_covariance, numeric,
numeric) IS 'covariance aggregate transition function';


-- Need to include a check for N equal zero data points

CREATE OR REPLACE FUNCTION public.numeric_covariance(_covariance)
    RETURNS numeric AS '
    BEGIN
    (_covariance.xy/_covariance.n) -
(_covariance.x/_covariance.n)*(_covariance.y/_covariance.n);
    END;
    'LANGUAGE 'plpgsql' IMMUTABLE STRICT;
GRANT EXECUTE ON FUNCTION public.numeric_covariance(_covariance) TO public;
COMMENT ON FUNCTION public.numeric_covariance(_covariance) IS
'covariance aggregate final function';



CREATE AGGREGATE public.covariance(
  BASETYPE=numeric,
  SFUNC=covariance_accum,
  STYPE=numeric[],
  FINALFUNC=numeric_covariance,
  INITCOND='{0,0,0,0}'
);


/*
--I also tried this:

CREATE AGGREGATE covariance(
  BASETYPE='numeric, numeric',
  SFUNC=covariance_accum,
  STYPE=numeric[],
  FINALFUNC=numeric_covariance,
  INITCOND='{0,0,0,0}'
);

-- to no avail.
*/

Regards,
Berend



Вложения

В списке pgsql-general по дате отправления:

Предыдущее
От: Scott Marlowe
Дата:
Сообщение: Re: Postgres Disconnection problems
Следующее
От: Bruno Wolff III
Дата:
Сообщение: Re: SQL Help: Multiple LEFT OUTER JOINs