❖ Aggregates |
Aggregates reduce a collection of values into a single result.
Examples:
count()sum()max()
The action of an aggregate function can be viewed as:
State = initial state
for each item T {
# update State to include T
State = updateState(State, T)
}
return makeFinal(State)
❖ Aggregates (cont) |
Aggregates are commonly used with GROUP BY
In that context, they "summarise" each group.
Example:
R select a,sum(b),count(*) a | b | c from R group by a ---+---+--- 1 | 2 | x a | sum | count 1 | 3 | y ---+-----+------- 2 | 2 | z 1 | 5 | 2 2 | 1 | a 2 | 6 | 3 2 | 3 | b
❖ User-defined Aggregates |
SQL standard does not specify user-defined aggregates.
But PostgreSQL provides a mechanism for defining them.
To define a new aggregate, first need to supply:
❖ User-defined Aggregates (cont) |
New aggregates defined using CREATE AGGREGATE
AggName(BaseType) ( CREATE AGGREGATE= UpdateStateFunction, sfunc= StateType, stype= InitialValue, initcond= MakeFinalFunction, finalfunc= OrderingOperator ); sortop
initcondNULLfinalfuncsortop❖ User-defined Aggregates (cont) |
Example: defining the count
create aggregate myCount(anyelement) (
stype = int, -- the accumulator type
initcond = 0, -- initial accumulator value
sfunc = oneMore -- increment function
);
create function
oneMore(sum int, x anyelement) returns int
as $$
begin return sum + 1; end;
$$ language plpgsql;
❖ User-defined Aggregates (cont) |
Example: sum2
create type IntPair as (x int, y int); create function addPair(sum int, p IntPair) returns int as $$ begin return sum + p.x + p.y; end; $$ language plpgsql; create aggregate sum2(IntPair) ( stype = int, initcond = 0, sfunc = addPair );
❖ User-defined Aggregates (cont) |
PostgreSQL has many aggregates (e.g. sumcount
But it doesn't have a product aggregate.
Implement a prod
select prod(*) from iota(5); prod ------ 120
❖ User-defined Aggregates (cont) |
Example: product aggregate
create function mult(soFar numeric, next numeric) returns numeric as $$ begin return soFar * next; end; $$ language plpgsql; create aggregate prod(numeric) ( stype = numeric, initcond = 1, sfunc = mult );
❖ User-defined Aggregates (cont) |
Define a concat
select count(*), concat(name) from Employee;
-- returns e.g.
count | concat
-------+----------------------
4 | John,Jane,David,Phil
❖ User-defined Aggregates (cont) |
Example: string concatenation aggregate
create function
join(s1 text, s2 text) returns text
as $$
begin
if (s1 = '') then
return s2;
else
return s1||','||s2;
end if;
end;
$$ language plpgsql;
create aggregate concat(text) (
stype = text,
initcond = '',
sfunc = join
);
Produced: 15 Oct 2020