我在找到解决这个问题的正确方法时遇到了一些麻烦。
Database tables:
Student(stdID[pk], stdName, stdSet)
Enrollment(stdID[pk], crsID[pk], year[pk], semester[pk], grade)
Offering(crsID[pk], year[pk], semester[pk], instrID)
Course(crsID[pk], crsTitle, creditHrs)
Instructor(instrID[pk], instrName, dept)
“查找从2006年到2008年教授给定学生A01234567的所有讲师。列出学生ID,讲师ID和年份。不要重复行。”
我原来的是这个:
SELECT DISTINCT stdID, instrID, year
FROM Student s
JOIN Instructor i ON Offering o (o.instrID = i.instrID)
JOIN Offering o ON Course c (c.crsID = o.crsID)
WHERE stdID = 'A01234567'
AND date BETWEEN (2006 AND 2008);
但是,这并不完全正确。我注意到这与“在提供加入中缺少2列”有关,但我不知道这意味着什么......
答案 0 :(得分:2)
您的联接语法不正确。这是您的查询,已修复,因此它至少在语法上是正确的。这可能会帮助您实现解决方案:
SELECT DISTINCT stdID, instrID, year
FROM Instructor i JOIN
Offering o
ON o.instrID = i.instrID join
Course c
on c.crsID = o.crsID
WHERE stdID = 'A01234567' AND date BETWEEN (2006 AND 2008);
答案 1 :(得分:1)
从概念上讲,我会从Instructor
表开始,因为这就是我想要返回的内容。
我将其加入Offering
表,因此我为每位教师提供了所有Offering
。
(但我们根本不需要Instructor
表中的任何内容,因为我们在Offering
表中有InstrId。)
然后我加入Enrollment
,基本上让所有参加每门课程的学生都参加。
然后我加入Student
。但同样,我们并不需要Student
表中的任何内容,我们在stdId
表中已经有Enrollment
。
棘手的部分是Offering
和Enrollment
之间的联接。联接谓词需要位于year
和semester
以及crsId
。
因此,为了满足规定的要求,只需要查询两个表:
SELECT e.stdId
, o.instrId
, e.year
FROM Offering o
JOIN Enrollment e
ON e.crsId = o.crsId
AND e.year = o.year
AND e.semester = o.semester
WHERE e.stdID = 'A01234567'
AND e.year >= 2006
AND e.year <= 2008
GROUP
BY e.stdId
, o.instrId
, e.year
ORDER
BY e.stdId
, o.instrId
, e.year
数据库设计有一个特点。考虑当同一年和一学期有两名或更多教师教授某门课程时会发生什么。
但是这名学生只参加了其中一项。
此查询将选择两种产品的教师。
这是查询的问题,但是给定的数据库设计没有给我们任何解决问题的方法...因为没有办法告诉学生哪个教师。
查询满足规定的要求,但结果有点奇怪,显示一名特定学生在2006年秋季为“Calc I”提供了六位不同的教师。
除非有什么东西在这里躲避我。
修改
正如Emily Litella所说的那样,“没关系......”。 Offering
表上有一个唯一约束。一学期只能提供给定crsId
的一个。{1}}。所以那里没问题。 (除非特定学期在给定学期中只提供一门课程,否则很奇怪。)
GROUP BY
不是必需的。约束已经保证不会返回重复的行。
实际上,我认为需要GROUP BY,因为学生可能会参加由同一个教师领导的两个单独的课程。 GROUP BY
的目的是消除结果集中的任何重复行(如规范中所示)。