Reputation: 1670
I have the following piece of code:
case when status=status2 and rank=5 then datediff(day, rep_onboard_date, client_signup_date) end as time_to_status2
where:
rank= row_number() over(partition by rep_id order by client_signup_date)
and:
status2= case when count(client_signup_date) over (partition by rep_id) >=5
.
This takes the time difference between rep_onboard_date
and client_signup_date
of his 5th client.
This works fine however only the 5th row per rep is populated, while the rest are (null).
What I would like is that if any row is populated for the rep with time_to_status
then all rows should carry the same value.
Simplified query:
with cte as (
select rep_id, rep_onboard_date, user_id, client_signup_date, /* a bunch of other fields,*/
count(client_signup_date) over (partition by rep_id) as total_applicants,
case when count(client_signup_date) over (partition by rep_id) >=10 then 'status1'
when count(client_signup_date) over (partition by rep_id) >=5 then 'status2'
when count(client_signup_date) over (partition by rep_id) >=1 then 'status3'
else 'none' end status,
row_number() over(partition by rep_id order by client_signup_date) as rank,
from table1 r
left join table2 u on r.user_id=u.user_id
left join table3 pi on u.user_id=pi.user_id
)
select *,
case when status='status1' and rank=10 then datediff(day, advisor_onboard_date, client_signup_date) end as time_to_status1,
case when status='status2' and rank=5 then datediff(day, advisor_onboard_date, client_signup_date) end as time_to_status2,
case when status='status3' and rank=1 then datediff(day, advisor_onboard_date, client_signup_date) end as time_to_status3
from cte
Current output:
rep_id user_id rep_onboard_date client_signup_date status rank time_to_status
1 1 1/1/2018 1/5/2018 status2 1 (null)
1 2 1/1/2018 1/5/2018 status2 2 (null)
1 3 1/1/2018 1/6/2018 status2 3 (null)
1 4 1/1/2018 1/7/2018 status2 4 (null)
1 5 1/1/2018 1/10/2018 status2 5 9
1 6 1/1/2018 1/15/2018 status2 6 (null)
Expected output:
rep_id user_id rep_onboard_date client_signup_date status rank time_to_status
1 1 1/1/2018 1/5/2018 status2 1 9
1 2 1/1/2018 1/5/2018 status2 2 9
1 3 1/1/2018 1/6/2018 status2 3 9
1 4 1/1/2018 1/7/2018 status2 4 9
1 5 1/1/2018 1/10/2018 status2 5 9
1 6 1/1/2018 1/15/2018 status2 6 9
Upvotes: 1
Views: 78
Reputation: 1269563
I believe what you want are window functions:
select cte.*,
max(case when status = 'status1' and rank = 10
then datediff(day, advisor_onboard_date, client_signup_date)
end) over (partition by rep_id) as time_to_status1
from cte;
Upvotes: 1
Reputation: 10277
It seems you don't want a CASE
, you want a subquery. Something like this:
SELECT col1,
col2,
(SELECT datediff(day, rep_onboard_date, client_signup_date)
FROM yourTable t2
WHERE t2.rep_id = t.rep_id
AND ((t.rank = 10 AND t.status = 'status')
OR (t.rank = 5 AND t.status = 'status2')
OR (t.rank = 1 AND t.status = 'status3'))) as time_to_status
FROM (yourTable or derivedTable with rank function) t
Upvotes: 1