Students who have taken the test for every course in their degree
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}
I've been trying to do a "Not exist" approach to isolate the answer, but I think I've gone a bit too deep. I'm limited to essentially only using like really basic stuff for my intro to database class. So, basically only INNER JOIN, UNION, and CASE and maybe a few other stuff, but probably best assume like the bare bones stuff. We're not allowed to use coalesce yet.
sql postgresql
add a comment |
I've been trying to do a "Not exist" approach to isolate the answer, but I think I've gone a bit too deep. I'm limited to essentially only using like really basic stuff for my intro to database class. So, basically only INNER JOIN, UNION, and CASE and maybe a few other stuff, but probably best assume like the bare bones stuff. We're not allowed to use coalesce yet.
sql postgresql
how did stu002 manage to take an exam this isnt in a course?
– Caius Jard
Oct 29 '18 at 21:38
since we don't see from the question if there is a course table or not "Calc C" might exist, but not be mandatory for any specific program?
– Preli
Oct 29 '18 at 21:45
add a comment |
I've been trying to do a "Not exist" approach to isolate the answer, but I think I've gone a bit too deep. I'm limited to essentially only using like really basic stuff for my intro to database class. So, basically only INNER JOIN, UNION, and CASE and maybe a few other stuff, but probably best assume like the bare bones stuff. We're not allowed to use coalesce yet.
sql postgresql
I've been trying to do a "Not exist" approach to isolate the answer, but I think I've gone a bit too deep. I'm limited to essentially only using like really basic stuff for my intro to database class. So, basically only INNER JOIN, UNION, and CASE and maybe a few other stuff, but probably best assume like the bare bones stuff. We're not allowed to use coalesce yet.
sql postgresql
sql postgresql
edited Nov 23 '18 at 15:07
Anon Li
asked Oct 29 '18 at 20:33
Anon LiAnon Li
457
457
how did stu002 manage to take an exam this isnt in a course?
– Caius Jard
Oct 29 '18 at 21:38
since we don't see from the question if there is a course table or not "Calc C" might exist, but not be mandatory for any specific program?
– Preli
Oct 29 '18 at 21:45
add a comment |
how did stu002 manage to take an exam this isnt in a course?
– Caius Jard
Oct 29 '18 at 21:38
since we don't see from the question if there is a course table or not "Calc C" might exist, but not be mandatory for any specific program?
– Preli
Oct 29 '18 at 21:45
how did stu002 manage to take an exam this isnt in a course?
– Caius Jard
Oct 29 '18 at 21:38
how did stu002 manage to take an exam this isnt in a course?
– Caius Jard
Oct 29 '18 at 21:38
since we don't see from the question if there is a course table or not "Calc C" might exist, but not be mandatory for any specific program?
– Preli
Oct 29 '18 at 21:45
since we don't see from the question if there is a course table or not "Calc C" might exist, but not be mandatory for any specific program?
– Preli
Oct 29 '18 at 21:45
add a comment |
3 Answers
3
active
oldest
votes
Not sure if this is possible with just INNER JOIN, UNION, and CASE -> but I found a solution with an outer join (still quite simple).
Lets try to solve this in two steps.
1) Lets see which students have NOT finished all their classes
select s.code
from programs p inner join students s on (p.degree = s.degree)
left outer join exams e on (e.course = p.course and e.student = s.code)
where e.course is null
We join programs with students and then left outer join the exams and filter only those rows where no exam row could be matched (which means the student has not taken the exam yet)
2) We get all students that are NOT returned by this query (meaning they have finished all required courses)
select
code, name
from student where code not in (
select s.code
from programs p inner join students s on (p.degree = s.degree)
left outer join exams e on (e.course = p.course and e.student = s.code)
where e.course is null
)
add a comment |
I like using aggregation for these things.
select s.code, s.name, s.degree
from students s join
programs p
on p.degree = s.degree join
exams e
on e.student = s.code and e.course = p.course
group by s.code, s.name, s.degree
having count(distinct e.course) = (select count(*) from programs p2 where p2.degree = p.degree);
Note that this includes the degree
as well as the student. After all, students could double major.
add a comment |
In a similar vein to Preli's answer, I'd use a left join to highlight exams that had not been taken:
SELECT s.code, s.name, p.course
FROM
students s
INNER JOIN
programs p
ON (p.degree = s.degree)
This is effectively the list of exams a student must take for the course
Now add on the exams they have taken, and leave nulls for those they havent:
SELECT s.code, s.name, p.course, e.course
FROM
students s
INNER JOIN
programs p
ON (p.degree = s.degree)
LEFT OUTER JOIN
exams e
ON e.student = s.code AND e.course = p.course
The results would look like:
Code | Name | p.Course | e.Course
stu001 | John | Calc A | Calc A
stu001 | John | Calc B | Calc B
stu002 | Doe | Calc A | <null>
stu002 | Doe | Calc B | <null>
Now reduce it to a list of just students that have taken an exam for every course. We can do this by checking that the COUNT(e.course) is the same as the COUNT(p.course) because NULL isn't counted by COUNT() so any occurrences of null (no exam) in e.course reduce the count, compared to counting the overall occurrences of p.course (i could also have used count(*)):
SELECT s.code, s.name
FROM
students s
INNER JOIN
programs p
ON (p.degree = s.degree)
LEFT OUTER JOIN
exams e
ON e.student = s.code AND e.course = p.course
GROUP BY s.code, s.name
HAVING COUNT(p.course) = COUNT(e.course)
John's COUNT(p.Course) would be 2 and COUNT(e.course) would also be 2, so he shows (just once, because he's grouped. Doe's COUNT(p.course) is 2 but COUNT(e.course) is 0, because all values are null, and 2 != 0 so he is hidden
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53053400%2fstudents-who-have-taken-the-test-for-every-course-in-their-degree%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
Not sure if this is possible with just INNER JOIN, UNION, and CASE -> but I found a solution with an outer join (still quite simple).
Lets try to solve this in two steps.
1) Lets see which students have NOT finished all their classes
select s.code
from programs p inner join students s on (p.degree = s.degree)
left outer join exams e on (e.course = p.course and e.student = s.code)
where e.course is null
We join programs with students and then left outer join the exams and filter only those rows where no exam row could be matched (which means the student has not taken the exam yet)
2) We get all students that are NOT returned by this query (meaning they have finished all required courses)
select
code, name
from student where code not in (
select s.code
from programs p inner join students s on (p.degree = s.degree)
left outer join exams e on (e.course = p.course and e.student = s.code)
where e.course is null
)
add a comment |
Not sure if this is possible with just INNER JOIN, UNION, and CASE -> but I found a solution with an outer join (still quite simple).
Lets try to solve this in two steps.
1) Lets see which students have NOT finished all their classes
select s.code
from programs p inner join students s on (p.degree = s.degree)
left outer join exams e on (e.course = p.course and e.student = s.code)
where e.course is null
We join programs with students and then left outer join the exams and filter only those rows where no exam row could be matched (which means the student has not taken the exam yet)
2) We get all students that are NOT returned by this query (meaning they have finished all required courses)
select
code, name
from student where code not in (
select s.code
from programs p inner join students s on (p.degree = s.degree)
left outer join exams e on (e.course = p.course and e.student = s.code)
where e.course is null
)
add a comment |
Not sure if this is possible with just INNER JOIN, UNION, and CASE -> but I found a solution with an outer join (still quite simple).
Lets try to solve this in two steps.
1) Lets see which students have NOT finished all their classes
select s.code
from programs p inner join students s on (p.degree = s.degree)
left outer join exams e on (e.course = p.course and e.student = s.code)
where e.course is null
We join programs with students and then left outer join the exams and filter only those rows where no exam row could be matched (which means the student has not taken the exam yet)
2) We get all students that are NOT returned by this query (meaning they have finished all required courses)
select
code, name
from student where code not in (
select s.code
from programs p inner join students s on (p.degree = s.degree)
left outer join exams e on (e.course = p.course and e.student = s.code)
where e.course is null
)
Not sure if this is possible with just INNER JOIN, UNION, and CASE -> but I found a solution with an outer join (still quite simple).
Lets try to solve this in two steps.
1) Lets see which students have NOT finished all their classes
select s.code
from programs p inner join students s on (p.degree = s.degree)
left outer join exams e on (e.course = p.course and e.student = s.code)
where e.course is null
We join programs with students and then left outer join the exams and filter only those rows where no exam row could be matched (which means the student has not taken the exam yet)
2) We get all students that are NOT returned by this query (meaning they have finished all required courses)
select
code, name
from student where code not in (
select s.code
from programs p inner join students s on (p.degree = s.degree)
left outer join exams e on (e.course = p.course and e.student = s.code)
where e.course is null
)
edited Oct 29 '18 at 21:23
answered Oct 29 '18 at 21:15
PreliPreli
1,56362742
1,56362742
add a comment |
add a comment |
I like using aggregation for these things.
select s.code, s.name, s.degree
from students s join
programs p
on p.degree = s.degree join
exams e
on e.student = s.code and e.course = p.course
group by s.code, s.name, s.degree
having count(distinct e.course) = (select count(*) from programs p2 where p2.degree = p.degree);
Note that this includes the degree
as well as the student. After all, students could double major.
add a comment |
I like using aggregation for these things.
select s.code, s.name, s.degree
from students s join
programs p
on p.degree = s.degree join
exams e
on e.student = s.code and e.course = p.course
group by s.code, s.name, s.degree
having count(distinct e.course) = (select count(*) from programs p2 where p2.degree = p.degree);
Note that this includes the degree
as well as the student. After all, students could double major.
add a comment |
I like using aggregation for these things.
select s.code, s.name, s.degree
from students s join
programs p
on p.degree = s.degree join
exams e
on e.student = s.code and e.course = p.course
group by s.code, s.name, s.degree
having count(distinct e.course) = (select count(*) from programs p2 where p2.degree = p.degree);
Note that this includes the degree
as well as the student. After all, students could double major.
I like using aggregation for these things.
select s.code, s.name, s.degree
from students s join
programs p
on p.degree = s.degree join
exams e
on e.student = s.code and e.course = p.course
group by s.code, s.name, s.degree
having count(distinct e.course) = (select count(*) from programs p2 where p2.degree = p.degree);
Note that this includes the degree
as well as the student. After all, students could double major.
answered Oct 29 '18 at 22:21
Gordon LinoffGordon Linoff
794k37318423
794k37318423
add a comment |
add a comment |
In a similar vein to Preli's answer, I'd use a left join to highlight exams that had not been taken:
SELECT s.code, s.name, p.course
FROM
students s
INNER JOIN
programs p
ON (p.degree = s.degree)
This is effectively the list of exams a student must take for the course
Now add on the exams they have taken, and leave nulls for those they havent:
SELECT s.code, s.name, p.course, e.course
FROM
students s
INNER JOIN
programs p
ON (p.degree = s.degree)
LEFT OUTER JOIN
exams e
ON e.student = s.code AND e.course = p.course
The results would look like:
Code | Name | p.Course | e.Course
stu001 | John | Calc A | Calc A
stu001 | John | Calc B | Calc B
stu002 | Doe | Calc A | <null>
stu002 | Doe | Calc B | <null>
Now reduce it to a list of just students that have taken an exam for every course. We can do this by checking that the COUNT(e.course) is the same as the COUNT(p.course) because NULL isn't counted by COUNT() so any occurrences of null (no exam) in e.course reduce the count, compared to counting the overall occurrences of p.course (i could also have used count(*)):
SELECT s.code, s.name
FROM
students s
INNER JOIN
programs p
ON (p.degree = s.degree)
LEFT OUTER JOIN
exams e
ON e.student = s.code AND e.course = p.course
GROUP BY s.code, s.name
HAVING COUNT(p.course) = COUNT(e.course)
John's COUNT(p.Course) would be 2 and COUNT(e.course) would also be 2, so he shows (just once, because he's grouped. Doe's COUNT(p.course) is 2 but COUNT(e.course) is 0, because all values are null, and 2 != 0 so he is hidden
add a comment |
In a similar vein to Preli's answer, I'd use a left join to highlight exams that had not been taken:
SELECT s.code, s.name, p.course
FROM
students s
INNER JOIN
programs p
ON (p.degree = s.degree)
This is effectively the list of exams a student must take for the course
Now add on the exams they have taken, and leave nulls for those they havent:
SELECT s.code, s.name, p.course, e.course
FROM
students s
INNER JOIN
programs p
ON (p.degree = s.degree)
LEFT OUTER JOIN
exams e
ON e.student = s.code AND e.course = p.course
The results would look like:
Code | Name | p.Course | e.Course
stu001 | John | Calc A | Calc A
stu001 | John | Calc B | Calc B
stu002 | Doe | Calc A | <null>
stu002 | Doe | Calc B | <null>
Now reduce it to a list of just students that have taken an exam for every course. We can do this by checking that the COUNT(e.course) is the same as the COUNT(p.course) because NULL isn't counted by COUNT() so any occurrences of null (no exam) in e.course reduce the count, compared to counting the overall occurrences of p.course (i could also have used count(*)):
SELECT s.code, s.name
FROM
students s
INNER JOIN
programs p
ON (p.degree = s.degree)
LEFT OUTER JOIN
exams e
ON e.student = s.code AND e.course = p.course
GROUP BY s.code, s.name
HAVING COUNT(p.course) = COUNT(e.course)
John's COUNT(p.Course) would be 2 and COUNT(e.course) would also be 2, so he shows (just once, because he's grouped. Doe's COUNT(p.course) is 2 but COUNT(e.course) is 0, because all values are null, and 2 != 0 so he is hidden
add a comment |
In a similar vein to Preli's answer, I'd use a left join to highlight exams that had not been taken:
SELECT s.code, s.name, p.course
FROM
students s
INNER JOIN
programs p
ON (p.degree = s.degree)
This is effectively the list of exams a student must take for the course
Now add on the exams they have taken, and leave nulls for those they havent:
SELECT s.code, s.name, p.course, e.course
FROM
students s
INNER JOIN
programs p
ON (p.degree = s.degree)
LEFT OUTER JOIN
exams e
ON e.student = s.code AND e.course = p.course
The results would look like:
Code | Name | p.Course | e.Course
stu001 | John | Calc A | Calc A
stu001 | John | Calc B | Calc B
stu002 | Doe | Calc A | <null>
stu002 | Doe | Calc B | <null>
Now reduce it to a list of just students that have taken an exam for every course. We can do this by checking that the COUNT(e.course) is the same as the COUNT(p.course) because NULL isn't counted by COUNT() so any occurrences of null (no exam) in e.course reduce the count, compared to counting the overall occurrences of p.course (i could also have used count(*)):
SELECT s.code, s.name
FROM
students s
INNER JOIN
programs p
ON (p.degree = s.degree)
LEFT OUTER JOIN
exams e
ON e.student = s.code AND e.course = p.course
GROUP BY s.code, s.name
HAVING COUNT(p.course) = COUNT(e.course)
John's COUNT(p.Course) would be 2 and COUNT(e.course) would also be 2, so he shows (just once, because he's grouped. Doe's COUNT(p.course) is 2 but COUNT(e.course) is 0, because all values are null, and 2 != 0 so he is hidden
In a similar vein to Preli's answer, I'd use a left join to highlight exams that had not been taken:
SELECT s.code, s.name, p.course
FROM
students s
INNER JOIN
programs p
ON (p.degree = s.degree)
This is effectively the list of exams a student must take for the course
Now add on the exams they have taken, and leave nulls for those they havent:
SELECT s.code, s.name, p.course, e.course
FROM
students s
INNER JOIN
programs p
ON (p.degree = s.degree)
LEFT OUTER JOIN
exams e
ON e.student = s.code AND e.course = p.course
The results would look like:
Code | Name | p.Course | e.Course
stu001 | John | Calc A | Calc A
stu001 | John | Calc B | Calc B
stu002 | Doe | Calc A | <null>
stu002 | Doe | Calc B | <null>
Now reduce it to a list of just students that have taken an exam for every course. We can do this by checking that the COUNT(e.course) is the same as the COUNT(p.course) because NULL isn't counted by COUNT() so any occurrences of null (no exam) in e.course reduce the count, compared to counting the overall occurrences of p.course (i could also have used count(*)):
SELECT s.code, s.name
FROM
students s
INNER JOIN
programs p
ON (p.degree = s.degree)
LEFT OUTER JOIN
exams e
ON e.student = s.code AND e.course = p.course
GROUP BY s.code, s.name
HAVING COUNT(p.course) = COUNT(e.course)
John's COUNT(p.Course) would be 2 and COUNT(e.course) would also be 2, so he shows (just once, because he's grouped. Doe's COUNT(p.course) is 2 but COUNT(e.course) is 0, because all values are null, and 2 != 0 so he is hidden
edited Oct 30 '18 at 8:45
answered Oct 30 '18 at 8:38
Caius JardCaius Jard
12.5k21440
12.5k21440
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53053400%2fstudents-who-have-taken-the-test-for-every-course-in-their-degree%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
how did stu002 manage to take an exam this isnt in a course?
– Caius Jard
Oct 29 '18 at 21:38
since we don't see from the question if there is a course table or not "Calc C" might exist, but not be mandatory for any specific program?
– Preli
Oct 29 '18 at 21:45