按组计算活动用户的运行总数

时间:2019-04-08 12:38:56

标签: mysql sql running-total

我需要根据组找到系统中活动用户的运行总数 如果用户当前处于暂停状态,则不应在当前计数中考虑该用户,而应在其活跃时考虑该用户 对于前 用户在2019年4月被停职,因此在进行所有计数之前,应该将他视为活跃用户

“用户”表包含状态(“活动” /“已暂停”)和“更新”列 我已经编写了代码,但是由于仅考虑当前的活动用户,因此并没有达到预期效果

 SELECT DISTINCT Concat(year(b1.created_at),'-',monthname(b1.created_at)) Date,c1.name as 'GroupName',
(   
    select 
    count(distinct(b.user_id))      from 
        users u2 join teams_users b on u2.id = b.user_id join teams c on b.team_id = c.id  
    where 
    year(b.created_at)*100 + month(b.created_at) <= year(b1.created_at)*100+month(b1.created_at)
     and 
    u2.organization_id =1690 
             and u2.status = 'Active' 
    and c.organization_id = 1690 
     and c.id =c1.id
    ) total_users
 from users u1 join teams_users b1 on u1.id = b1.user_id 
 join teams c1 on b1.team_id = c1.id
 where 
     u1.organization_id =1690  and u1.status = 'Active'

用户

 UserId|CreatedOn|Status|Updatedon

团队

 Id|Name

Team_users

 Team_id|User_id|CreatedOn

1 个答案:

答案 0 :(得分:0)

Here's a sample query that will get you a total number of users in a given month, per month, per team:

with generator as
(
SELECT 0 n UNION ALL SELECT 1  UNION ALL SELECT 2  UNION ALL 
   SELECT 3   UNION ALL SELECT 4  UNION ALL SELECT 5  UNION ALL
   SELECT 6   UNION ALL SELECT 7  UNION ALL SELECT 8  UNION ALL
   SELECT 9   UNION ALL SELECT 10 UNION ALL SELECT 11 UNION ALL
   SELECT 12  
),
user_to_team as
(
   select user_id
        , team_id
        , tu.created_at as date_joined
        , case 
            when u.status = 'suspended'
            then u.updatedon
            else curdate()
          end member_until
     from team_users tu
     join users u
       on u.id = tu.user_id
), periods as
(
   select year*100 + month as period
     from (select 2018+n as year from generator where n < 2) x
    cross
     join (select 1+n as month from generator where n<12) y
)
select periods.period
     , t.id
     , count(u2t.user_id)
  from periods
  join teams t
    on year(t.created_at) * 100 + month(t.created_at) <= periods.period
  left outer
  join user_to_team u2t
    on periods.period between year(u2t.date_joined)*100 + month(u2t.date_joined) and year(u2t.member_until)*100 + month(u2t.member_until)
   and u2t.team_id = t.id
 where periods.period <= year(curdate())*100 + month(curdate())
group by periods.period, t.id
order by periods.period, t.id

generator CTE is for generating numbers, we'll need that in periods to generate a list of year-months (yyyymm). If you have a numbers table, you can use that. user_to_team CTE just lists the relations between users with when they joined (record in user_teams created) and until when they were members (either updatedon of the user if they are suspended, or current date). Then it's just a matter of joining our periods to teams and the user_to_team to that based on dates - teams are joined ever since they were created and members to period between which they existed.

Here's a working sample on dbfiddle

There are two teams:

  • team 1 created in 2019-01
  • team 2 created in 2019-02

Users:

  • user 1, active
  • user 2, suspended since 2019-03

Team to User:

  • user 1 in team 1 since 2019-01, in team 2 since 2019-03
  • user 2 in team 1 since 2019-03, in team 2 since 2019-03