I have a table with entity name, year and activity number as
bellow. During some years there is not any activity.
name | year | act_num
-----+------+---------
aa | 2000 | 2
aa | 2001 | 6
aa | 2002 | 9
aa | 2003 | 15
aa | 2005 | 17
b | 2000 | 3
b | 2002 | 4
b | 2003 | 9
b | 2005 | 12
b | 2006 | 2
To create it on postgresql;
CREATE TABLE entity_year_activity (
name character varying(10),
year integer,
act_num integer
);
INSERT INTO entity_year_activity
VALUES
('aa', 2000, 2),
('aa', 2001, 6),
('aa', 2002, 9),
('aa', 2003, 15),
('aa', 2005, 17),
('b', 2000, 3),
('b', 2002, 4),
('b', 2003, 9),
('b', 2005, 12),
('b', 2006, 2);
I would like to have the total number of the past x years with the
number of this year activities for each entity for every year as bellow.
As an example for x = three years.
name | year | act_num | total_3_years
-----+------+---------+---------------
aa | 2000 | 2 | 2
aa | 2001 | 6 | 8
aa | 2002 | 9 | 17
aa | 2003 | 15 | 30
aa | 2004 | 0 | 24
aa | 2005 | 17 | 32
b | 2000 | 3 | 3
b | 2001 | 0 | 3
b | 2002 | 4 | 7
b | 2003 | 9 | 13
b | 2005 | 12 | 21
b | 2006 | 2 | 14
Here’s an approach that uses the ability to use the
sumaggregate as a window function with a range-based window frame – seeSUM(...) OVER (PARTITION BY name ORDER BY year ROWS 2 PRECEDING)and window framing.See SQLFiddle.
The need to generate entries for years that have no entry themselves complicates this query. I generate a table of all (name, year) pairs, then
left outer join entity_year_activityon it before doing the window sum, so all years for all name sets are represented. That’s why this is so complicated. Then I filter the aggregated result to exclude entries with zero in the sum.