Reputation: 658
I'm new to Postgres and I'm looking to retrieve a list of courses that a particular set of users are enrolled in as course leaders in the same course(s). Hopefully I've explained that clearly.
It's returning a list of all the courses that that all the users are enrolled in as course leader rather than a list of the same courses that they are enrolled in as course leader.
This is my original query
select distinct(cm.course_id), cm.course_name, cm.dtcreated, cm.dtmodified
from course_main cm
inner join course_users cu on cm.pk1 = cu.crsmain_pk1
inner join users u on u.pk1 = cu.users_pk1
where u.user_id IN ('msassar5','mfztsjc3', 'mzysshba', 'mftssag3', 'mfztslmi', 'mfztsml7', 'mtlsscm5', 'msdsshp2', 'mzysscp9', 'mcyssmy')
and role = 'P' - 'P' denotes course leader
and cm.service_level = 'F' -- 'F' denotes full course
order by cm.course_id, cm.dtcreated asc
I need to compare all the courses that each of the users are enrolled in as course leader (P) and only display the courses that are in each list, but I'm not sure the best approach.
I've read about the INTERSECT statement and using that does produce the result I expect, but that seems to be an inelegant solution as I would have to add another query to the INTERSECT list for each additional user.
Here is me INTERSECT query
select distinct(cm.course_id), cm.course_name, cm.dtcreated, cm.dtmodified
from course_main cm
inner join course_users cu on cm.pk1 = cu.crsmain_pk1
left outer join users u on u.pk1 = cu.users_pk1
where u.user_id = '<USERNAME>'
and role = 'P'
and cm.service_level = 'F'
intersect
select distinct(cm.course_id), cm.course_name, cm.dtcreated, cm.dtmodified
from course_main cm
inner join course_users cu on cm.pk1 = cu.crsmain_pk1
left outer join users u on u.pk1 = cu.users_pk1
where u.user_id = '<USERNAME>'
and role = 'P'
and cm.service_level = 'F'
intersect
...
...
...
Here is my result, which is correct. This is the only course that ALL the users in my query are enrolled in
Is there a more elegant solution?
Any help will be appreciated.
thanks
Upvotes: 1
Views: 112
Reputation: 1270011
If you want an intersection -- that is courses where all 10 users are leaders -- then use aggregation and a having
clause:
select cm.course_id, cm.course_name, cm.dtcreated, cm.dtmodified
from course_main cm join
course_users cu
on cm.pk1 = cu.crsmain_pk1 join
users u
on u.pk1 = cu.users_pk1
where u.user_id in ('msassar5', 'mfztsjc3', 'mzysshba', 'mftssag3', 'mfztslmi', 'mfztsml7', 'mtlsscm5', 'msdsshp2', 'mzysscp9', 'mcyssmy') and
role = 'P' and
cm.service_level = 'F' -- 'F' denotes full course
group by cm.course_id
having count(*) = 10;
Upvotes: 1