Skip to content

Instantly share code, notes, and snippets.

@portnov
Created October 5, 2023 16:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save portnov/30a8baea257fd0c2442884abf4c932e3 to your computer and use it in GitHub Desktop.
Save portnov/30a8baea257fd0c2442884abf4c932e3 to your computer and use it in GitHub Desktop.
create table tst_array(
id int primary key generated always as identity,
ts int not null,
value int[] not null
);
insert into tst_array (ts, value)
select
(i / 20)::int,
array(
select distinct (random()*(i % 10 + 1))::int
from generate_series(1, (random()*(i % 5) + 2)::int)
)
from generate_series(1, 1000) g (i);
create or replace function set_union(st anyarray, v anyarray) returns anyarray as $$
select array_agg(distinct x)
from unnest(st || v) u (x)
$$ language sql immutable;
create or replace function set_diff(st1 anyarray, st2 anyarray) returns anyarray as $$
select array(
select v
from unnest(st1) u (v)
except
select v
from unnest(st2) u (v)
)
$$ language sql immutable;
create aggregate set_union_agg(anyarray) (
sfunc = set_union,
stype = anyarray,
initcond = '{}'
);
select id, ts, value, agg, set_diff(agg, lag(agg) over (partition by ts order by id))
from (
select id, ts, value, set_union_agg(value) over (partition by a.ts order by a.id) agg
from tst_array a
order by a.id, a.ts
) sub;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment