Multi-parameter aggregates.

From: Berend Tober <btober(at)seaworthysys(dot)com>
To: pgsql-general(at)postgresql(dot)org
Subject: Multi-parameter aggregates.
Date: 2005-11-21 16:03:22
Message-ID: 4381EFCA.2030708@seaworthysys.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: 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

Attachment Content-Type Size
btober.vcf text/x-vcard 233 bytes

Responses

Browse pgsql-general by date

  From Date Subject
Next Message Hakan Kocaman 2005-11-21 16:23:44 Re: Multi-parameter aggregates.
Previous Message Chris Kratz 2005-11-21 15:50:45 Rule appears not to fire on insert w/ "except"