Reputation: 1088
There are a number of locations with members at different steps in an ordinal process. The members can be in multiple processes with different progress at one or more locations.
The join table between locations and members could look something like this called steps.
| id | member_id | step_no | location_id | process_id |
-------------------------------------------------------
| 1 | 1 | 2 | 10 | 57
| 2 | 1 | 5 | 10 | 58
| 3 | 2 | 5 | 11 | 37
| 4 | 2 | 1 | 10 | 57
I have not been able to figure how to get a unique count of members, by location, for the furthest step the member is in the process.
location_id | 1 | 2 | 3 | 4 | 5 |
---------------------------------
10 | 1 | 0 | 0 | 0 | 1 |
11 | 0 | 0 | 0 | 0 | 1 |
So far, I have this query:
SELECT count(DISTINCT m.id), l.id, l.name
FROM members m
INNER JOIN steps s ON m.id = s.member_id
INNER JOIN locations l ON s.location_id = l.id
WHERE step_no = 5
GROUP BY l.id
ORDER BY l.name
But this only returns step_no = 5, of course, and if I wrote five of these queries, the member could be counted twice at different steps.
Upvotes: 3
Views: 3690
Reputation: 131
1- First select the following into a temp table:
select location_id , step_no , count(member_id) as count
into stepsPrime
from (select member_id, location_id, max(step_no) as step_no
from steps
group by member_id, location_id ) definedTab
group by location_id, step_no
order by location_id;
2- Use the following query to pivot the above results:
select distinct stp.location_id,
stp1.count as step1,
stp2.count as step2,
stp3.count as step3,
stp4.count as step4,
stp5.count as step5
from stepsPrime stp
left join stepsPrime stp1 on stp.location_id = stp1.location_id and stp1.step_no = 1
left join stepsPrime stp2 on stp.location_id = stp2.location_id and stp2.step_no = 2
left join stepsPrime stp3 on stp.location_id = stp3.location_id and stp3.step_no = 3
left join stepsPrime stp4 on stp.location_id = stp4.location_id and stp4.step_no = 4
left join stepsPrime stp5 on stp.location_id = stp5.location_id and stp5.step_no = 5;
Upvotes: 0
Reputation: 68
select
location_id
,sum(case when max_step = 1 then 1 else 0 end) as step_one_cnt
,sum(case when max_step = 2 then 1 else 0 end) as step_two_cnt
,sum(case when max_step = 3 then 1 else 0 end) as step_three_cnt
,sum(case when max_step = 4 then 1 else 0 end) as step_four_cnt
,sum(case when max_step = 5 then 1 else 0 end) as step_five_cnt
FROM
(select
s.location_id,
s.member_id,
max(s.step_no) as max_step
FROM steps S
group by 1,2
) as base
group by 1
Breaking it down, the base query gives you the following result:
member_id | location_id | max_step_no
-------------------------------------------------------
| 1 | 10 | 5
| 2 | 10 | 1
| 2 | 11 | 5
The aggregation query on this subquery (base), basically pivots the result into the form you would like to see it. The only limitation of this approach is that the number of steps is statically defined in advanced.
Upvotes: 1