多表连接查询(JOIN)
当需要查询的数据分散在不同表中时,就需要通过"公共字段"把它们关联起来。
举个例子:
学生表 S(SNO, SNAME, AGE, SEX, SDEPT) 选课表 SC(SNO, CNO, GRADE) 课程表 C(CNO, CNAME, CDEPT, TNAME) 字段含义包括:SNO 学号、SNAME 姓名、SEX 性别、SDEPT 系别、CNO 课程号。
要求:检索学习课程号为 C2 的学生学号与姓名。
sql
SELECT DISTINCT S.SNO, S.SNAME
FROM S
JOIN SC ON S.SNO = SC.SNO
WHERE SC.CNO = 'C2';
为什么需要 JOIN?
题目要求"学号 + 姓名",但:
-
学号(SNO)在 S 表 和 SC 表 中都有
-
姓名(SNAME)只在 S 表 中
-
课程号(CNO)只在 SC 表 中
所以必须把 S 表和 SC 表"拼"在一起,才能同时拿到这些信息。
JOIN 的工作原理
JOIN SC ON S.SNO = SC.SNO 的意思是:
把 S 表的每一行和 SC 表的每一行做匹配,只保留学号相等的那些组合。
关于 DISTINCT
如果一个学生选了同一门课有多条记录(比如重修),JOIN 后会出现重复行。DISTINCT 就是用来去重的。不过在这个题目中,SC 表的主键通常是 (SNO, CNO) 的组合,理论上不会重复,加 DISTINCT 更多是保险写法。
等价的另一种写法
这道题也可以用子查询实现,效果一样:
sql
SELECT SNO, SNAME
FROM S
WHERE SNO IN (
SELECT SNO FROM SC WHERE CNO = 'C2'
);
思路是:先从 SC 表找出学了 C2 的所有学号,再去 S 表查这些学号对应的姓名。