多表查询
等值连接查询和非等值连接查询
JOIN ON
自然连接
自身连接
注意,如果属性名在参与连接的各个表中是唯一的,可以省略表名前缀。
外连接
多表查询进阶
这里输出的列名可以重命名
自身连接
Select Distinct T2.* from Teacher t1, teacher t2
where t1.name = 'Mr.Zhang' and t2.age > t1.age;
连接与笛卡尔积
关系代数之连接和除法
集合查询
并操作
交操作
差操作
关于以下代码正确的是:
(SELECT Name
FROM Student
WHERE Age >= 25
UNION
SELECT Name
FROM Student
WHERE Age <= 30
)
INTERSECT
(SELECT Name
FROM Teacher
WHERE Dept IN ('CS','EE','ML')
EXCEPT
SELECT Name
FROM Teacher
WHERE Gender = 'F'
)
并操作
嵌套查询
集合比较与SOME关键字
集合比较与ALL关键字
EXIST关键字
FROM嵌套与HAVING
WITH关键字
练习
这次我们先从简单的来,使用 EXISTS 关键字在授课信息表 Teaches(CourseID, TeacherID, Capacity)中查询出同时教授 CS223 和 CS233 两门课的教师的编号 TeacherID。
以下三句话等效:
SELECT TeacherID
FROM Teaches AS T1
WHERE CourseID = 'CS223'
AND
EXISTS (
SELECT * FROM Teaches AS T2
WHERE CourseID = 'CS233'
AND
T1.TeacherID = T2.TeacherID);
SELECT TeacherID
FROM Teaches
WHERE CourseID = 'CS223'
AND
TeacherID IN (
SELECT TeacherID
FROM Teaches
WHERE CourseID = 'CS233');
SELECT T1.TeacherID
FROM Teaches T1, Teaches T2
WHERE T1.CourseID = 'CS223'
AND
T2.CourseID = 'CS233'
AND
T1.TeacherID= T2.TeacherID;
做完上面三步,大家可以检查一下三次查询的结果是不是一致的。
下面我们来满足一个稍微复杂且奇怪点的需求,要求大家查询出 EE 这个学院中,有哪个老师是教授过选课信息表上出现过的所有的课程的,要求大家使用 NOT EXISTS 关键字查询出符合条件的教师的姓名Name、性别 Gender 和专业 Major。下面给出几张有可能用到的表,供大家参考。
授课信息表 Teaches(CourseID, TeacherID, Capacity)
教师信息表 Teacher(TeacherID, Name, Age, Gender, Major, Dept)
选课信息表 Takes(CourseID, ID, Semester, Year, Grade)
这个查询比较复杂,但实际上是有一个固定的模式的
SELECT Name,Gender,Major
FROM Teacher
WHERE Dept = 'EE' AND NOT EXISTS
(SELECT *
FROM Takes
WHERE NOT EXISTS
(SELECT *
FROM Teaches
WHERE TeacherID = Teacher.TeacherID
AND CourseID = Takes.CourseID
)
);
当然符合上面要求的教师几乎是不可能出现的。我们来做一个现实一点地题目,要求大家查询出这样一类同学的编号 ID,他们选了教授 CS222 这门课的老师所教授的全部课程。同样的要求大家使用 NOT EXSITS 关键字进行嵌套查询,这一题的代码跟上一步有点像哦。可能使用到的表有如下几个:
授课信息表 Teaches(CourseID, TeacherID, Capacity)
教师信息表 Teacher(TeacherID, Name, Age, Gender, Major, Dept)
选课信息表 Takes(CourseID, ID, Semester, Year, Grade)
大家先不要看提示,自己写一写代码,再来对照一下有哪些不一致的地方。
SELECT ID
FROM Takes AS T1
WHERE NOT EXISTS
(SELECT *
FROM Teaches AS T2
WHERE
CourseID = 'CS222'
AND NOT EXISTS
(SELECT *
FROM Teaches AS T3
WHERE T1.CourseID = T3.CourseID
AND T2.TeacherID = T3.TeacherID));