-1

我很难理解创建视图 TRANSCRIPTVIEW 是如何设法为那些没有参加课程的人设置 0 级的。解释会有所帮助,解决方案和问题如下。谢谢。

学生(ID,姓名)成绩单(StudId,课程名称,学期,年级)

用 SQL 编写以下查询: 创建所有学生(Id、Name)的列表,并为每个学生列出 S2002 学期所学课程的平均成绩。请注意,可能有学生在 S2002 中没有参加任何课程。对于这些,平均成绩应列为 0。 解决方案:我们首先创建一个视图,该视图在 TRANSCRIPT 中添加行,这些行将每个学生注册到一个分数为 0 的 NULL 课程。因此,在 '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
4

2 回答 2

1

how the create view, TRANSCRIPTVIEW, manages to set the grade of 0 for those who did not take a course

在 S2002 学期未参加课程的学生集合在该学期的成绩单表中没有记录。那些确实在那个学期上过课程的人确实在那个学期的表中记录了一个记录。NULL, 'S2002',0如果学生不在 S2002 学期的成绩单表中,则查询会为他们提供值:

  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’
   ) 
于 2013-03-22T18:04:14.587 回答
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 时不会有这些缺点。

于 2013-03-22T17:55:29.297 回答