Querying DAU/MAU over time (daily)

前端 未结 4 1379
礼貌的吻别
礼貌的吻别 2021-02-04 07:08

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:

         


        
4条回答
  •  一向
    一向 (楼主)
    2021-02-04 07:40

    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=>
    

提交回复
热议问题