无法理解SQL中的这个视图是如何工作的

时间:2013-03-22 17:48:22

标签: sql database

我很难理解创建视图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

2 个答案:

答案 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。