PostgreSQL aggregate function over range

不想你离开。 提交于 2020-01-15 11:53:10

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!