Table semesters:
semesterID startDate
1 2013-01-01
2 2013-03-01
3 2013-06-01
Table classes:
classID class_title semesterID
1 Math 1
2 Science 1
3 Math 2
4 Science 2
5 Math 3
6 Science 3
Table persons:
personID firstName lastName
1 John Jones
2 Steve Smith
Table class_person:
classID personID
1 1
2 1
5 1
6 1
3 2
4 2
5 2
6 2
I need to get a list of all the people, with the first semester in which they took a class (semester with the oldest startDate).
firstName, lastName, semesterID, startDate
John Jones 1 2013-01-01
Steve Smith 2 2013-03-01
I've spent hours trying to figure this out. Here's the closest I've gotten (although it is not close at all!):
SELECT p.firstName, p.lastName, MIN(s.startDate) AS min_startDate
FROM semesters s
INNER JOIN classes c ON s.semesterID = c.semesterID
INNER JOIN class_person cp ON cp.classID = c.classID
INNER JOIN persons p ON p.personID = cp.personID
GROUP BY cs.personID
ORDER BY min_startDate, p.lastName, p.firstName
Any help would be massively appreciated. Thank you.
You could end up using a monster like the following (fiddle):
The subquery
pidentifies all persons. For each,pswill contain a single row. ItspersonIDis simply copied, itssemesterIDis computed by a subquery, which sorts semesters by date but returns the ID. The outermost query then re-adds the date.If you don't really need the
semesterID, you could avoid one layer. If your semesters are in order, i.e. their IDs have the same order as their startDates, then you could simply use a single query, much like your own, and returnmin(semesterID)andmin(startDate).On the whole, this question reminds me a lot of my own question, Select one value from a group based on order from other columns. Answers suggested there will likely apply here as well. In particular, there are approaches using user variables which I still don't feel comfortable about, but which will make this whole mess a lot easier and seem to work well enough. So adapting this answer, you get a query like this (fiddle):
I'll leave adapting the other answers as an excercise.