Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MySQL - Group By Number of Users within Ranges of Unique Login Days and by Department

Tags:

sql

mysql

I'm working on a query right now that will count the number of unique login days per user, place them in a bucket (1-2, 3-4 log in days etc.), and return the number of each users in each bucket by department. I apologize if this isn't too clear, and hopefully the examples below will help illustrate my question.

I have a table like this:

+-------------+-----------+------------+-----------------+
|    time     | user_name |    dept    |      event      |
+-------------+-----------+------------+-----------------+
| 2016-01-04  | Joe       | finance    | logged in       |
| 2016-01-04  | Jeff      | marketing  | logged in       |
| 2016-01-04  | Jeff      | marketing  | project created |
| 2016-01-04  | Bob       | finance    | logged in       |
| 2016-01-04  | Mark      | accounting | logged in       |
| 2016-01-05  | Bob       | finance    | logged in       |
| 2016-01-08  | Bob       | finance    | logged in       |
| 2016-01-09  | Jeff      | marketing  | logged in       |
| 2016-01-10  | Jeff      | marketing  | logged in       |
| 2016-01-11  | Nate      | accounting | logged in       |
| 2016-01-11  | Nate      | accounting | project created |
+-------------+-----------+------------+-----------------+

I want to return a table like this:

+------------------+-----------------+------------+
| number of logins | number of users |    dept    |
+------------------+-----------------+------------+
| 1-2              |               1 | finance    |
| 3-4              |               1 | finance    |
| 5+               |               0 | finance    |
| 1-2              |               0 | marketing  |
| 3-4              |               1 | marketing  |
| 5+               |               0 | marketing  |
| 1-2              |               2 | accounting |
| 3-4              |               0 | accounting |
| 5+               |               0 | accounting |
+------------------+-----------------+------------+ 

As of now, my query looks like:

select 
(case when count(distinct(`time`)) between 1 and 2 then '1-2' 
      when count(distinct(`time`)) between 3 and 4 then '3-4'
      else '5+'
        end) as buckets, dept, user_name
    from change_log where event in ('logged in')  
    group by dept, user_name

However, this is returning a table like below, which is the closest I could get to what I want, but I'm not sure how to roll it up to just by the buckets and department.

+---------+------------+-----------+
| buckets |    dept    | user_name |
+---------+------------+-----------+
| 1-2     | accounting | Mark      |
| 1-2     | accounting | Nate      |
| 3-4     | finance    | Bob       |
| 1-2     | finance    | Joe       |
| 3-4     | marketing  | Jeff      |
+---------+------------+-----------+
like image 777
kstern Avatar asked Jan 18 '16 19:01

kstern


1 Answers

Something like this?

select buckets, dept, count(user_name) no_of_u from 
(select 
(case when count(distinct(`time`)) between 1 and 2 then '1-2' 
      when count(distinct(`time`)) between 3 and 4 then '3-4'
      else '5+'
        end) as buckets, dept, user_name
    from change_log where event in ('logged in')  
    group by dept, user_name)
group by buckets, dept
like image 89
Nomeaning25 Avatar answered Nov 15 '22 06:11

Nomeaning25