I have a daily sessions table with columns user_id and date. I\'d like to graph out DAU/MAU (daily active users / monthly active users) on a daily basis. For example:
You didn't show us your complete table definition, but maybe something like this:
select date,
count(*) over (partition by date_trunc('day', date) order by date) as dau,
count(*) over (partition by date_trunc('month', date) order by date) as mau
from sessions
order by date;
To get the percentage without repeating the window functions, just wrap this in a derived table:
select date,
dau,
mau,
dau::numeric / (case when mau = 0 then null else mau end) as pct
from (
select date,
count(*) over (partition by date_trunc('day', date) order by date) as dau,
count(*) over (partition by date_trunc('month', date) order by date) as mau
from sessions
) t
order by date;
Here is an example output:
postgres=> select * from sessions; session_date | user_id --------------+--------- 2014-05-01 | 1 2014-05-01 | 2 2014-05-01 | 3 2014-05-02 | 1 2014-05-02 | 2 2014-05-02 | 3 2014-05-02 | 4 2014-05-02 | 5 2014-06-01 | 1 2014-06-01 | 2 2014-06-01 | 3 2014-06-02 | 1 2014-06-02 | 2 2014-06-02 | 3 2014-06-02 | 4 2014-06-03 | 1 2014-06-03 | 2 2014-06-03 | 3 2014-06-03 | 4 2014-06-03 | 5 (20 rows) postgres=> select session_date, postgres-> dau, postgres-> mau, postgres-> round(dau::numeric / (case when mau = 0 then null else mau end),2) as pct postgres-> from ( postgres(> select session_date, postgres(> count(*) over (partition by date_trunc('day', session_date) order by session_date) as dau, postgres(> count(*) over (partition by date_trunc('month', session_date) order by session_date) as mau postgres(> from sessions postgres(> ) t postgres-> order by session_date; session_date | dau | mau | pct --------------+-----+-----+------ 2014-05-01 | 3 | 3 | 1.00 2014-05-01 | 3 | 3 | 1.00 2014-05-01 | 3 | 3 | 1.00 2014-05-02 | 5 | 8 | 0.63 2014-05-02 | 5 | 8 | 0.63 2014-05-02 | 5 | 8 | 0.63 2014-05-02 | 5 | 8 | 0.63 2014-05-02 | 5 | 8 | 0.63 2014-06-01 | 3 | 3 | 1.00 2014-06-01 | 3 | 3 | 1.00 2014-06-01 | 3 | 3 | 1.00 2014-06-02 | 4 | 7 | 0.57 2014-06-02 | 4 | 7 | 0.57 2014-06-02 | 4 | 7 | 0.57 2014-06-02 | 4 | 7 | 0.57 2014-06-03 | 5 | 12 | 0.42 2014-06-03 | 5 | 12 | 0.42 2014-06-03 | 5 | 12 | 0.42 2014-06-03 | 5 | 12 | 0.42 2014-06-03 | 5 | 12 | 0.42 (20 rows) postgres=>