问题
I am trying to create a function that will find the intersection of tsrange
, but I can't get it work:
CREATE AGGREGATE intersection ( tsrange ) (
SFUNC = *,
STYPE = tsrange
)
回答1:
There are two modifications to your attempt. First, I don't think you can use an operator as the SFUNC, so you need to define a named function to do the intersection, and use that.
CREATE or REPLACE FUNCTION int_tsrange(a tsrange, b tsrange)
returns tsrange language plpgsql as
'begin return a * b; end';
Secondly, the default value for a range is the empty range -- so the intersection will always be empty. You need to initialize the range to an infinite range '[,]'
to begin the aggregate. The aggregate definition then looks like:
CREATE AGGREGATE intersection ( tsrange ) (
SFUNC = int_tsrange,
STYPE = tsrange,
INITCOND = '[,]'
);
回答2:
If interested, it is possible to define a single function for all range types:
CREATE OR REPLACE FUNCTION range_intersection(a ANYRANGE, b ANYRANGE) RETURNS ANYRANGE
AS $$
SELECT a * b;
$$ LANGUAGE sql IMMUTABLE STRICT;
CREATE AGGREGATE range_intersection_agg(ANYRANGE) (
SFUNC = range_intersection,
STYPE = ANYRANGE,
INITCOND = '(,)'
);
SELECT range_intersection_agg(rng)
FROM (VALUES (int4range(1, 10)), (int4range(2, 20)), (int4range(4, NULL))) t (rng)
-- outputs [4,10)
来源:https://stackoverflow.com/questions/16822856/postgresql-aggregate-function-over-range