具有多个Where子句的SQL Count函数

时间:2014-05-04 17:55:52

标签: sql count

无法获得一段代码来为我的生活工作。

SELECT FirstName, LastName, sum(CASE WHEN FinalGrade='A' then 1 else 0 end)
FROM Person
JOIN Registration ON Person.Id = Registration.PersonId
JOIN Course ON Person.FacultyId = Course.FacultyId
WHERE Course.FacultyId = 9 AND FinalGrade='A'
GROUP BY FirstName, LastName;

表格是:

Person
iD    FirstName    LastName    FacultyId

Registration
iD    CourseId     PersonId    FinalGrade

Course
iD    FacultyId    Name        Code            EAP        GradeType

我希望它能回到我身边

FirstName,LastName,(在特定教师课程中获得的A&#39的总数)

它应该返回1到3之间的数字,但它返回一个人获得A * 10的时间

编辑:

我刚刚从头开始,只让PersonId工作,然后转移到名称,我就让它工作了。

SELECT FirstName, LastName, count(*)
FROM Registration 
JOIN Course ON Course.Id = Registration.CourseId
JOIN Person ON Person.Id = Registration.PersonId
WHERE Course.FacultyId = 9 AND FinalGrade = 'A'
Group by FirstName, LastName;

我仍然不太明白出了什么问题,但现在我已经改变了From并加入了。

我和那些有类似问题的人可以从这里离开是重要的,因为你从条款中使用了什么。

2 个答案:

答案 0 :(得分:2)

enter image description here 让我们简化表并使用一些测试数据

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   |
+----+-----------+--------+

Join子句(来自您的第一个查询)给出 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          |
+----+-----------+----------+-----------+----+----------+----------+------------+

并进一步加入课程 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   |
+----+-----------+----------+-----------+----+----------+----------+------------+----+-----------+--------+

按" FirstName,LastName"分组给一个群体带FirstName =' John'和LastName ='史密斯'并且该组正好包含这3条记录。所以这个' John Smith'的计数(*)功能。如你预期的那样,小组评估为3而不是1。

连接条件ON Person.FacultyId = Course.FacultyId(没有进一步限制)是问题所在。 它将第一次加入的每一行与来自同一教师的所有课程相结合。我还假设Person.FacultyId不一定必须与course.FacultyId相同。但即使他们必须与“沃尔特琼斯”相同。行不会消失,但结果仍然是错误的。

另一方面,您可以检查第二个查询是否会准确返回您想要的数据。

当我在我的一条评论中重新编写时,您的解决方案还有另一个问题。如果有两个学生具有相同的FirstName和LastName,如果您不通过Person.Id区分它们,您将把它们视为一个人。因此,您应该将Person.Id添加到group by子句(GROUP BY FirstName, LastName, Person.Id)中,以便为每个学生获取单独的记录。如果将person.Id添加到SELECT子句中,即使两个学生使用相同的名称,也会将结果行分配给相应的学生。

答案 1 :(得分:0)

可能您不需要注册表,或者您错过了注册表和Corse表之间的连接条件。如果与多个注册注册相关联的人可以生产带有课程的笛卡尔产品。

PS

并注意上面的评论。