Let's simplify the table and use some test data
Person +----+-----------+----------+-----------+ | Id | FirstName | LastName | FacultyId | +----+-----------+----------+-----------+ | p1 | John | Smith | 9 | | p2 | Walter | Jones | 4 | +----+-----------+----------+-----------+ Registration +----+----------+----------+------------+ | Id | CourseId | PersonId | FinalGrade | +----+----------+----------+------------+ | r1 | c1 | p1 | A | | r2 | c2 | p1 | B | | r3 | c3 | p2 | A | +----+----------+----------+------------+ Course +----+-----------+--------+ | Id | FacultyId | Name | +----+-----------+--------+ | c1 | 9 | Java | | c2 | 9 | Python | | c3 | 9 | Ruby | +----+-----------+--------+
the Join clause (from your first query) gives
Person JOIN Registration ON Person.Id = Registration.PersonId
+---------------------------------------+---------------------------------------+ | Person | Registration | +----+-----------+----------+-----------+----+----------+----------+------------+ | Id | FirstName | LastName | FacultyId | Id | CourseId | PersonId | FinalGrade | +----+-----------+----------+-----------+----+----------+----------+------------+ | p1 | John | Smith | 9 | r1 | c1 | p1 | A | | p1 | John | Smith | 9 | r2 | c2 | p1 | B | | p2 | Walter | Jones | 4 | r3 | c3 | p2 | A | +----+-----------+----------+-----------+----+----------+----------+------------+
and joining further with Course gives
Person JOIN Registration ON Person.Id = Registration.PersonId JOIN Course ON Person.FacultyId = Course.FacultyId
+---------------------------------------+---------------------------------------+-------------------------+ | Person | Registration | Course | +----+-----------+----------+-----------+----+----------+----------+------------+----+-----------+--------+ | Id | FirstName | LastName | FacultyId | Id | CourseId | PersonId | FinalGrade | Id | FacultyId | Name | +----+-----------+----------+-----------+----+----------+----------+------------+----+-----------+--------+ | p1 | John | Smith | 9 | r1 | c1 | p1 | A | c1 | 9 | Java | | p1 | John | Smith | 9 | r1 | c1 | p1 | A | c2 | 9 | Python | | p1 | John | Smith | 9 | r1 | c1 | p1 | A | c3 | 9 | Ruby | | p1 | John | Smith | 9 | r2 | c2 | p1 | B | c1 | 9 | Java | | p1 | John | Smith | 9 | r2 | c2 | p1 | B | c2 | 9 | Python | | p1 | John | Smith | 9 | r2 | c2 | p1 | B | c3 | 9 | Ruby | +----+-----------+----------+-----------+----+----------+----------+------------+----+-----------+--------+ now apply the where clause "WHERE Course.FacultyId = 9 AND FinalGrade='A'" +---------------------------------------+---------------------------------------+-------------------------+ | Person | Registration | Course | +----+-----------+----------+-----------+----+----------+----------+------------+----+-----------+--------+ | Id | FirstName | LastName | FacultyId | Id | CourseId | PersonId | FinalGrade | Id | FacultyId | Name | +----+-----------+----------+-----------+----+----------+----------+------------+----+-----------+--------+ | p1 | John | Smith | 9 | r1 | c1 | p1 | A | c1 | 9 | Java | | p1 | John | Smith | 9 | r1 | c1 | p1 | A | c2 | 9 | Python | | p1 | John | Smith | 9 | r1 | c1 | p1 | A | c3 | 9 | Ruby | +----+-----------+----------+-----------+----+----------+----------+------------+----+-----------+--------+
grouping by "FirstName, LastName" give one group with FirstName='John' and LastName='Smith' and that group contains exactly these 3 records. So the count(*) function on this 'John Smith' group evaluates to 3 and not to 1 as you have expected.
The join condition ON Person.FacultyId = Course.FacultyId
(without further restriction) is the problem.
It combines each row from the first join with all courses from the same faculty. I also assumed that there it is not necessary that the Person.FacultyId
must be the same as the course.FacultyId
. But even if they have to be the same the 'Walter Jones' rows would not disapear but the result will remain wrong.
On the other hand you can check that the second query will return exactly what you want for this data.
As I remaked in one of my comments there is another problem with your solution. If there are two students with the same FirstName and LastName you will treat them as one person if you don't distinguish them by ther Person.Id. So you should add Person.Id to the group by clause ( GROUP BY FirstName, LastName, Person.Id
) to get a separate record for each student. If you add person.Id
to the SELECT clause , too, you will assign the result rows to the appropriate studen even if two students habve the same names.