构建具有多个WHERE要求的SQL查询,一个有点复杂,丢失

时间:2013-11-24 21:36:48

标签: sql sql-server

我正在做家庭作业问题

  

我需要轮询三张桌子并查找少花钱的学生的名字   超过3.5 GPA,并且不到9学分

我已经想出如何填写少于9学分的学生的姓名,但我仍然坚持要求他们的学分。

学生表包含Student ID(主键),NameYear(新鲜,soph等),MajorGPA

课程表包含course ID(主键),Name of classcredit hour rating for that class

注册表包含Student ID(使其成为外键),Course1(FK),Course2Course3Course4

我不是在寻找'正确'的答案,而是一些方向感。

到目前为止,我的查询是

SELECT DISTINCT NAME 
From StudentTable,EnrollmentTable,CourseTable
WHERE (GPA <3.5)

我想在GPA检查后需要一些东西,分析每个学生的入学表,检查每门课程(Course1,Course2等),if!null,使用该课程ID并轮询课程表以查找学分该课程的价值。然后使用SUM检查是否&lt; 9。

思考?感谢您的帮助!

2 个答案:

答案 0 :(得分:2)

如果数据库模式由您决定,那么我会稍微更改一下。注册表示学生和课程之间的映射。我将它简化为两列:StudentID和CourseID(如果您不希望表的复合主键,则可以添加第三列EnrollmentID)。

执行此操作后,您可以加入学生 - &gt;注册 - &gt;课程。按学生ID分组,并使用学生学分的总和上的HAVING子句过滤,并使用学生GPA上的WHERE过滤。

有意义吗?

答案 1 :(得分:2)

您需要获得给定学生的学分时数总和,这应该引导您考虑一个小组

让我们把它分解。首先,您希望学生使用&lt; 3.5 GPA,这很简单:

SELECT S.Id, S.Name
FROM Student S
WHERE S.GPA < 3.5

通过为注册添加多个列而不是每个学生的注册中的多行(这将更为正常),它变得有点棘手

就个人而言,我会将其转换为“标准化”视图:

SELECT StudentId, Course1 AS CourseId
FROM Enrollment E
UNION
SELECT StudentId, Course2 AS CourseId
FROM Enrollment E
UNION
SELECT StudentId, Course3 AS CourseId
FROM Enrollment E
UNION
SELECT StudentId, Course4 AS CourseId
FROM Enrollment E

将其与第一个查询相结合:

SELECT S.Id, S.Name
FROM Student S
JOIN
(
    SELECT StudentId, Course1 AS CourseId
    FROM Enrollment E
    UNION
    SELECT StudentId, Course2 AS CourseId
    FROM Enrollment E
    UNION
    SELECT StudentId, Course3 AS CourseId
    FROM Enrollment E
    UNION
    SELECT StudentId, Course4 AS CourseId
    FROM Enrollment E
) E
  ON E.StudentId = S.StudentId
WHERE S.GPA < 3.5

然后你需要实际课程来获得CreditHourRating:

SELECT S.Id, S.Name, C.CreditHourRating
FROM Student S
JOIN
(
    SELECT StudentId, Course1 AS CourseId
    FROM Enrollment E
    UNION
    SELECT StudentId, Course2 AS CourseId
    FROM Enrollment E
    UNION
    SELECT StudentId, Course3 AS CourseId
    FROM Enrollment E
    UNION
    SELECT StudentId, Course4 AS CourseId
    FROM Enrollment E
) E
  ON E.StudentId = S.StudentId
JOIN Course C
  ON E.CourseId = C.CourseId
WHERE S.GPA < 3.5

然后您只需要每个学生的总数,因此查询变为:

SELECT S.Id, S.Name, SUM(C.CreditHourRating)
FROM Student S
JOIN
(
    SELECT StudentId, Course1 AS CourseId
    FROM Enrollment E
    UNION
    SELECT StudentId, Course2 AS CourseId
    FROM Enrollment E
    UNION
    SELECT StudentId, Course3 AS CourseId
    FROM Enrollment E
    UNION
    SELECT StudentId, Course4 AS CourseId
    FROM Enrollment E
) E
  ON E.StudentId = S.StudentId
JOIN Course C
  ON E.CourseId = C.CourseId
WHERE S.GPA < 3.5
GROUP BY S.Id, S.Name

最后,你在CreditHoursRating上有条件:

SELECT S.Id, S.Name, SUM(C.CreditHourRating)
FROM Student S
JOIN
(
    SELECT StudentId, Course1 AS CourseId
    FROM Enrollment E
    UNION
    SELECT StudentId, Course2 AS CourseId
    FROM Enrollment E
    UNION
    SELECT StudentId, Course3 AS CourseId
    FROM Enrollment E
    UNION
    SELECT StudentId, Course4 AS CourseId
    FROM Enrollment E
) E
  ON E.StudentId = S.StudentId
JOIN Course C
  ON E.CourseId = C.CourseId
WHERE S.GPA < 3.5
GROUP BY S.Id, S.Name
HAVING SUM(C.CreditHourRating) < 9