我很难理解创建视图TRANSCRIPTVIEW如何为未参加课程的人设置0级。解释会有所帮助,解决方案和问题如下。感谢。
学生(ID,姓名) 转录(StudId,CourseName,学期级)
在SQL中制定以下查询: 创建所有学生的名单(Id,姓名),并为每个学生列出S2002学期课程的平均成绩。 请注意,可能有学生在S2002中没有参加任何课程。对于这些,平均成绩应列为0。 解: 我们首先创建一个视图,该视图使用行将每个学生注册到0级为0的NULL课程中增加TRANSCRIPT。因此,在学期'S2002'中没有学习任何东西的学生将在该学期获得平均成绩0。
以下是令我困惑的,这是如何工作的以及为什么会起作用?
CREATE VIEW TRANSCRIPTVIEW AS (
( SELECT * FROM Transcipt)
UNION
(
SELECT S.Id,NULL,’S2002’,0
FROM Student S)
WHERE S.Id NOT IN (
SELECT T.StudId
FROM Transcript T
WHERE T.Semester = ’S2002’) )
)
Remaining solution:
SELECT S.Id, S.Name, AVG(T.Grade)
FROM Student S, TRANSCRIPTVIEW T
WHERE S.Id = T.StudId AND T.Semester = ’S2002’ GROUP BY S.Id
答案 0 :(得分:1)
how the create view, TRANSCRIPTVIEW, manages to set the grade of 0 for those who did not take a course
那个没有参加S2002学期课程的学生在该学期的成绩单表中没有记录。那个学期确实上过课程的人确实在那个学期的桌子上有记录。如果学生不在学期S2002的成绩单表中,则查询为学生提供值NULL, 'S2002',0
:
SELECT S.Id,NULL,’S2002’,0 FROM Student S) -- this parenthesis is wrong
-- this following where conditions looks for students NOT IN the 2002 subset:
WHERE S.Id NOT IN
-- this next part gets a list of studentids for semester 2002
(
SELECT T.StudId FROM Transcript T
WHERE T.Semester = ’S2002’
)
答案 1 :(得分:0)
你的问题解决方案很荒谬。更好的解决方案是:
SELECT S.Id, S.Name, AVG(case when T.Semester = ’S2002’ then T.Grade end) as AvgS2002Grade
FROM Student S left outer join
TRANSCRIPTVIEW T
on S.Id = T.StudId AND T.Semester = ’S2002’
GROUP BY S.Id
您问题中的查询过于复杂。由于性能原因,它使用union
(确实应该union all
)以确保包含所有学生。天哪,这就是left outer join
的用途。当条件聚合更合适时,它正在where
子句中进行过滤。它使用古老的连接语法,而不是ANSI标准。
我希望你不会因为这些缺点而学习SQL。