Reputation: 1604
I am having below two tables used in the join
TABLE1 : rat_proj_duration_map
Columns: UID,Hour_val,month_val
TABLE2 : users
Columns: UID, status, left_on
Here Status will contain texts('Act','InAct')
Now, I am trying to get count of UIDs grouped by month_val field as like below
select count(r.uid) as cnt, r.month_val
from rat_proj_duration_map r
inner join users u on r.uid = u.uid
where r.year_val = 2018
group by r.month_val
order by month_val
The above Query gives count of the records in month wise.
But, I am trying to ignore the 'Inactivated' users (Status field in users table) from the date(left_on from users table) of left.
So if the user was left on '2018-03-27', then that user record should be counted upto march month, not after that.
What's the condition to be added to my Query
Example Output: If there are 100 users records and one user left_on '2018-03-27' with status 'Inactivated' then my result should look like below
Count Month_val
100 1
100 2
100 3
99 4
99 5
99 6
99 7
99 8
99 9
99 10
99 11
99 12
Upvotes: 0
Views: 92
Reputation: 272096
I think you want this:
SELECT COUNT(CASE WHEN u.status = 'InAct' AND u.left_on < DATEADD(month, month_val - 1, DATEADD(year, year_val - 1900, 0)) THEN NULL ELSE 1 END) AS cnt, r.month_val
FROM rat_proj_duration_map r
INNER JOIN users u ON r.uid = u.uid
WHERE r.year_val = 2018
GROUP BY r.year_val, r.month_val
ORDER BY r.year_val, r.month_val
The expression DATEADD(month, month_val - 1, DATEADD(year, year_val - 1900, 0))
will convert 2018, 3
to 2018-03-01
. You need to NOT count those records where user status is a inactive and user left earlier than year-month-01.
Upvotes: 1
Reputation: 37357
You could try this query (necessary comments in code):
select [count] - [left_count] from
(
select [left_month_val],
--this will give amount of users left UP TO particular month
SUM([left_count]) over (order by [left_month_val] rows between unbounded preceding and current row) [left_count]
from (
--here you count how many users left in particular months
select DATEPART(month, [left_on]) [left_month_val], COUNT(*) [left_count]
from [users]
group by DATEPART(month, [left_on])
) [a]
) [u] join (
--here you count how many users were there in particular months
select [month_val], count(*) [count]
from rat_proj_duration_map
group by [month_val]
) [r] on [u].[left_month_val] = [r].[month_val]
Also, keep in mind that none of the query includes year, so you should add another grouping variable. Unfortunately, I couldn't try this myself, as you didn't give example data.
Upvotes: 1
Reputation: 14189
Filter the users by each project depending on their disable date. You can do this with an additional joining clause (or in the WHERE
in this case).
DECLARE @FilterYear INT = 2018
select
count(r.uid) as cnt,
r.month_val
from
rat_proj_duration_map r
inner join users u on r.uid = u.uid
where
r.year_val = @FilterYear AND
(
u.left_on IS NULL OR
YEAR(u.left_on) > @FilterYear OR
(YEAR(u.left_on) = @FilterYear AND R.month_val <= MONTH(u.left_on))
)
group by
r.month_val
order by
month_val
Keep in mind that we are comparing year and months (without days). You will have to consider what happens when the user is deactivated in the middle of the month.
Upvotes: 2
Reputation: 752
You can try this
select count(case when u.status='Act' then r.uid end) as cnt, r.month_val
from rat_proj_duration_map r
inner join users u on r.uid = u.uid
where r.year_val = 2018
group by r.month_val
order by month_val
Upvotes: -1