Подсчитать общее количество активных пользователей по группам - PullRequest
0 голосов
/ 08 апреля 2019

Мне нужно найти общее количество активных пользователей в системе на основе групп Если пользователь в данный момент заблокирован, его не следует учитывать в текущем подсчете, но следует учитывать, когда он был активным Для Ex Пользователь был отстранен от работы в апреле 2019 года, поэтому его следует считать активным пользователем до тех пор, пока все показатели не будут представлены в марте

.

Таблица пользователей содержит статус («Активен» / «Приостановлен») и обновлен в столбце Я написал код, но он не дает мне желаемого результата, поскольку учитывает только текущих активных пользователей

 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 голосов
/ 08 апреля 2019

Вот пример запроса, который даст вам общее количество пользователей за данный месяц, за месяц, на группу:

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 для генерации чисел, нам нужно это в periods для генерации списка лет-месяцев (yyyymm). Если у вас есть таблица numbers, вы можете использовать ее. user_to_team CTE просто перечисляет отношения между пользователями, с которыми они присоединились (запись в user_teams создана) и до тех пор, пока они не были участниками (либо updatedon пользователя, если они приостановлены, либо текущая дата). Тогда это просто вопрос присоединения наших periods к teams и user_to_team к этому на основе дат - команды объединяются с момента их создания и участники периода, между которым они существовали.

Вот рабочий пример на dbfiddle

Есть две команды:

  • команда 1, созданная в 2019-01
  • команда 2, созданная в 2019-02

Пользователи:

  • пользователь 1, активный
  • пользователь 2, приостановлено с 2019-03

Команда для пользователя:

  • пользователь 1 в команде 1 с 2019-01, в команде 2 с 2019-03
  • пользователь 2 в команде 1 с 2019-03, в команде 2 с 2019-03
...