Reputation: 41
I have the following table
startdate enddate activity
1/1/2015 1/3/2015 foo
1/2/2015 1/6/2015 bar
1/4/2015 1/7/2015 bar
How do i query to get the following daily sum?
date foo bar
1/1/2015 1 0
1/2/2015 1 1
1/3/2015 0 1
1/4/2015 0 2
1/5/2015 0 2
1/6/2015 0 1
1/7/2015 0 0
i'm using PSQL if that helps.
I'm assuming this is an easy question but i can't seem to find answer when i search. Perhaps i'm not using the right terminology to describe. thanks for any help
Upvotes: 2
Views: 104
Reputation: 4751
We can make it more dynamic by generating more activity cases.
With reference from Gordon Linoff's
answer , I have created postgresql function which can make it more dynamic for activity cases.
Check following function:
create or replace function sp_test()
returns void as
$$
declare cases character varying;
declare sql_statement text;
begin
select string_agg(distinct concat('sum((activity=','''',activity,'''',' )::int) as ',activity,' '),',') into cases from your_tbl;
drop table if exists temp_data;
sql_statement=concat('create temporary table temp_data as select t.dte, ',cases,'from
(select generate_series(startdate, enddate, interval ','''1 day''',') as dte,
activity
from your_tbl) as t group by t.dte order by t.dte');
execute sql_statement;
end;
$$
language 'plpgsql';
Function uses temporary table to store dynamic columns data.
Call function in following way to get data:
select * from sp_test(); select * from temp_data;
Upvotes: 0
Reputation: 1269803
You can use generate_series()
and aggregation. So, something like:
select dte,
sum((activity = 'foo')::int) as foo,
sum((activity = 'bar')::int) as bar
from (select generate_series(startdate, enddate, interval '1 day') as dte,
activity
from t
) t
group by dte
order by dte;
Note that generate_series()
is highly Postgres-specific. It is, however, highly convenient for this purpose.
Upvotes: 2