How to calculate percent?

后端 未结 2 1941
予麋鹿
予麋鹿 2020-12-22 10:03

Could you help me to calculate percent of users, which made payments? I\'ve got two tables:

activity
user_id  login_time
201      01.01.2017
202      01.01.2         


        
相关标签:
2条回答
  • 2020-12-22 10:29

    First you need a table with all days in the range. Since the range is small you can build an ad hoc derived table using UNION ALL. Then left join the payments and activities. Group by the day and calculate the percentage using the count()s.

    SELECT x.day,
           concat(CASE count(DISTINCT a.user_id)
                    WHEN 0 THEN
                      1
                    ELSE  
                      count(DISTINCT p.user_id)
                      /
                      count(DISTINCT a.user_id)
                  END
                  *
                  100,
                  '%')
           FROM (SELECT cast('2017-01-01' AS date) day
                 UNION ALL
                 SELECT cast('2017-01-02' AS date) day
                 UNION ALL
                 SELECT cast('2017-01-03' AS date) day
                 UNION ALL
                 SELECT cast('2017-01-04' AS date) day
                 UNION ALL
                 SELECT cast('2017-01-05' AS date) day) x
                LEFT JOIN payments p
                          ON p.payment_date = x.day
                LEFT JOIN activity a
                          ON a.login_time = x.day
                GROUP BY x.day;
    
    0 讨论(0)
  • 2020-12-22 10:51

    If you want the ratio of users who have made payments to those with activity, just summarize each table individually:

    select p.cnt / a.cnt
    from (select count(distinct user_id) as cnt from activity a) a cross join
         (select count(distinct user_id) as cnt from payment) p;
    

    EDIT:

    You need a table with all dates in the range. That is the biggest problem.

    Then I would recommend:

    SELECT d.dte,
           ( ( SELECT COUNT(DISTINCT p.user_id)
               FROM payments p
               WHERE p.payment_date >= d.dte and p.payment_date < d.dte + INTERVAL 1 DAY
              ) /
              NULLIF( (SELECT COUNT(DISTINCT a.user_id)
                       FROM activity a
                       WHERE a.login_time >= d.dte and p.login_time < d.dte + INTERVAL 1 DAY
                      ), 0
                     ) as ratio
    FROM (SELECT date('2017-01-01') dte UNION ALL
          SELECT date('2017-01-02') dte UNION ALL
          SELECT date('2017-01-03') dte UNION ALL
          SELECT date('2017-01-04') dte UNION ALL
          SELECT date('2017-01-05') dte 
         ) d;
    

    Notes:

    • This returns NULL on days where there is no activity. That makes more sense to me than 0.
    • This uses logic on the dates that works for both dates and date/time values.
    • The logic for dates can make use of an index, which can be important for this type of query.
    • I don't recommend using LEFT JOINs. That will multiply the data which can make the query expensive.
    0 讨论(0)
提交回复
热议问题