Reputation: 1832
My first query pulls out student details from 3 tables. Student, StudentAddress and StudentNote.
My query must list the student details, including id, name, address, note and find the earliest date they enrolled on a course.
I have created an aggregate query to do this.
SELECT STU_Name, MIN(ENR_StartDate)
FROM Student
INNER JOIN Enrolment
ON Student.STU_Student_ID = Enrolment.ENR_Student_ID
GROUP BY STU_Name
This is my main query which pull the details of the students.
SELECT STU_Name, ADD_Addr_Line_1, ADD_Addr_Line_2, ADD_Addr_Line_3, ADD_Postcode, NTE_Note, ENR_StartDate
FROM Student
INNER JOIN StudentAddress
ON Student.STU_Student_ID = StudentAddress.ADD_Student_ID
INNER JOIN StudentNote
ON Student.STU_Student_ID = StudentNote.NTE_Student_ID
INNER JOIN Enrolment
ON Student.STU_Student_ID = Enrolment.ENR_Student_ID
I want to link these queries so the result set tells me the earliest start date per student in the row.
Desired output for a student
row0: student1id, student1name, student1address, student1note1, student1startdate
row1: student1id, student1name, student1address, student1note2, student1startdate
This will allow a student to have multiple notes, but the start start will always be calculated as the same for a student.
I have built a test schema in sql fiddle.
http://sqlfiddle.com/#!2/cecea/4
Thanks for any help.
Upvotes: 2
Views: 97
Reputation: 264
Note that you have no noted for one of the students. That was corrected with an outer join.
In another case, you have 2 notes for one student. So that student has two rows in the result.
To resolve that, you need to choose a specific note (first, last, etc). You can do that using the same logic that is used to find the first enrollment record for each student.
Adjusted to handle cases where the student may have more than one row for the same enrollment date. This approach can be used to break most any of these types of ties. Note that window functions are usually a better approach, but MySQL does not support them.
SELECT STU_Name
, ADD_Addr_Line_1
, ADD_Addr_Line_2
, ADD_Addr_Line_3
, ADD_Postcode
, NTE_Note
, Enrolment.ENR_StartDate
, Enrolment.ENR_ID
, Student.STU_Student_ID
, StudentAddress.ADD_ID
, StudentNote.NTE_ID
FROM Student
JOIN StudentAddress
ON Student.STU_Student_ID = StudentAddress.ADD_Student_ID
LEFT JOIN StudentNote
ON Student.STU_Student_ID = StudentNote.NTE_Student_ID
JOIN Enrolment
ON Student.STU_Student_ID = Enrolment.ENR_Student_ID
LEFT JOIN Enrolment AS e2
ON Enrolment.ENR_Student_ID = e2.ENR_Student_ID
AND (Enrolment.ENR_StartDate, Enrolment.ENR_ID) > (e2.ENR_StartDate, e2.ENR_ID)
WHERE e2.ENR_StartDate IS NULL
;
Upvotes: 1
Reputation: 107686
You should add a table alias to all the columns to specify where they come from.
SELECT STU_Name, ADD_Addr_Line_1, ADD_Addr_Line_2, ADD_Addr_Line_3, ADD_Postcode, NTE_Note, ENR_StartDate,
G.EarliestStartDate
FROM Student
JOIN StudentAddress
ON Student.STU_Student_ID = StudentAddress.ADD_Student_ID
JOIN StudentNote
ON Student.STU_Student_ID = StudentNote.NTE_Student_ID
JOIN Enrolment
ON Student.STU_Student_ID = Enrolment.ENR_Student_ID
JOIN (
SELECT Student.STU_Student_ID, MIN(ENR_StartDate) EarliestStartDate
FROM Student
INNER JOIN Enrolment
ON Student.STU_Student_ID = Enrolment.ENR_Student_ID
GROUP BY STU_Name
) G on G.STU_Student_ID = Student.STU_Student_ID
Upvotes: 0