I need to find the running total of active users in the system based on the groups If a user is currently suspended he shouldn't be considered in the current count but should be considered when he was active For Ex A user got suspended in april 2019 so he should be considered as a active user till all the counts in march
The users table contains the status ('Active'/'Suspended') and updatedon column I have written the code but it doesn't give me the desired result as it only considers the current active users
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'
Users
UserId|CreatedOn|Status|Updatedon
Teams
Id|Name
Team_users
Team_id|User_id|CreatedOn
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:
Users:
Team to User:
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.