首页 > 解决方案 > 如何计算百分比?

问题描述

你能帮我计算一下付费用户的百分比吗?我有两张桌子:

activity
user_id  login_time
201      01.01.2017
202      01.01.2017
255      04.01.2017
255      05.01.2017
256      05.01.2017
260      15.03.2017

2

payments
user_id  payment_date
200      01.01.2017
202      01.01.2017
255      05.01.2017

我尝试使用此查询,但它计算出错误的百分比:

SELECT activity.login_time, (select COUNT(distinct payments.user_id) 
from payments where payments.payment_time between '2017-01-01' and 
'2017-01-05') / COUNT(distinct activity.user_id) * 100
AS percent
FROM payments INNER JOIN activity ON  
activity.user_id = payments.user_id and activity.login_time between 
'2017-01-01' and '2017-01-05'
GROUP BY activity.login_time;

我需要一个结果

01.01.2017  100 % 
02.01.2017  0% 
03.01.2017  0% 
04.01.2017  0% 
05.01.2017 - 50% 

标签: mysqlsqldatabaseselect

解决方案


如果您想了解已付款用户与有活动用户的比例,只需分别汇总每个表:

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;

编辑:

您需要一个包含该范围内所有日期的表格。这是最大的问题。

那么我会推荐:

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;

笔记:

  • 这将NULL在没有活动的日子返回。这对我来说比0.
  • 这使用适用于日期和日期/时间值的日期逻辑。
  • 日期逻辑可以使用索引,这对于此类查询很重要。
  • 我不建议使用LEFT JOINs。这将增加可能使查询变得昂贵的数据。

推荐阅读