当前位置:首页 > 问答 > 正文

和学生表还有课程表怎么弄联查,数据库里两个表数据咋关联查询才方便

要弄清楚学生表和课程表怎么联查,首先得明白这两个表里通常都存了些什么,想象一下,你是一个学校的教务管理员,你手头有两个最重要的花名册:一个是学生花名册(学生表),另一个是课程安排表(课程表)

学生表就像咱们班的花名册,里面主要记录每个学生的基本信息,根据网上常见的数据库设计例子(来源:各类数据库入门教程,如菜鸟教程、W3School等),它大概长这样:

  • student_id(学号):每个学生的唯一标识,就像你的身份证号,绝对不会重复。
  • student_name(学生姓名)
  • gender(性别)
  • class(班级)
  • 可能还有其他信息,比如入学年份、联系方式等。

课程表则记录了学校开设的所有课程,像一本课程目录:

和学生表还有课程表怎么弄联查,数据库里两个表数据咋关联查询才方便

  • course_id(课程编号):每门课的唯一标识,C001”代表“高等数学”。
  • course_name(课程名称)
  • teacher(任课老师)
  • credit(学分)
  • 可能还有上课地点、上课时间等。

现在问题来了:光有这两个表,你怎么知道“张三”这个学生,到底选了哪几门课呢?学生表里只有张三的个人信息,没有他选课的记录;课程表里只有课程信息,也没有记录哪个学生选了它,这就好像你有了一堆人名和一堆课程名,但不知道谁和谁对应。

这时候就需要一个“中间人”来牵线搭桥,这个“中间人”就是第三个表,通常叫做选课表成绩表(来源:关系型数据库核心概念——多对多关系),这个表是解决联查问题的关键,它的结构非常简单,但极其重要:

和学生表还有课程表怎么弄联查,数据库里两个表数据咋关联查询才方便

  • id(可选,一个自增的序号,为了管理方便)
  • student_id(学号):来自学生表。
  • course_id(课程编号):来自课程表。
  • 可能还有score(成绩),因为学生选了课最终会有成绩。

这个选课表的作用就是专门记录这种“谁选了啥”的关系,每一条记录都表示一个学生选了一门课,表里有这么一条记录:student_id是“S2023001”(张三的学号),course_id是“C001”(高等数学的编号),这就明确地记录了“张三选了高等数学”这件事。

好了,现在三个表都齐了,怎么关联查询才方便呢?这里就要用到SQL查询语句中的JOIN关键字(来源:SQL联表查询标准语法)。JOIN的意思就是“连接”,它能把不同表中有关联的数据行“拼”在一起。

和学生表还有课程表怎么弄联查,数据库里两个表数据咋关联查询才方便

最常用、最方便的就是INNER JOIN(内连接),它的逻辑是:只把那些在两个表里都能找到对应关系的数据行连接起来,具体到我们的例子,查询“张三选了哪些课”的SQL语句思路是这样的:

  1. 确定你想看什么信息:我们想看学生姓名和课程名称。
  2. 确定这些信息来自哪几个表:学生姓名来自学生表,课程名称来自课程表
  3. 确定通过哪个表把它们关联起来:通过选课表
  4. 写出SQL语句
SELECT
    s.student_name,  -- 从学生表里取姓名
    c.course_name    -- 从课程表里取课程名
FROM
    student s        -- 学生表,给它起个简短的别名`s`方便写
INNER JOIN
    selection sc     -- 连接选课表,别名`sc`
ON
    s.student_id = sc.student_id  -- 连接条件:学生表的学号要和选课表的学号相等
INNER JOIN
    course c         -- 再连接课程表,别名`c`
ON
    sc.course_id = c.course_id    -- 连接条件:选课表的课程号要和课程表的课程号相等
WHERE
    s.student_name = '张三';       -- 我们只关心张三的情况

我们来一步步理解这个“拼表”的过程:

  • 数据库会先从学生表里找到名叫“张三”的那一行。
  • 它拿着张三的student_id,去选课表里找,看看哪些记录的student_id和张三的一样,可能找到好几条,说明张三选了好几门课。
  • 它再根据找到的每一条选课记录里的course_id,去课程表里找到对应的课程名称。
  • 把“张三”这个名字,和他所选的每一门课的课程名,组合成最终的结果显示给你看。

这样查出来的结果,可能就是两列:一列是“张三”,另一列可能是“高等数学”;下一行是“张三”,另一列是“大学英语”,一目了然。

除了这种查询,关联查询还能做很多事:

  • 查询某门课有哪些学生选了:只要把上面SQL语句的WHERE条件改成c.course_name = '高等数学'就行了。
  • 查询每个学生选了几门课:这就会用到COUNT()函数和GROUP BY分组。
  • 即使学生没选课,也想把他显示出来:这时候就不能用INNER JOIN了,要用LEFT JOIN(左连接),它能保证学生表里所有的人都被列出,即使他在选课表里没有记录(没选任何课),对应的课程名会显示为NULL(空)。

让两个表(尤其是像学生和课程这种“多对多”关系的表)关联查询起来最方便的方法,就是建立一个中间表(选课表)来专门记录它们之间的关系,然后使用SQL的JOIN语句,通过这个中间表把两边需要的信息“桥接”起来,核心思路就是找到连接的条件(比如学号=学号课程号=课程号),数据库就会像拼图一样帮你把数据组合好,这种方法结构清晰,逻辑简单,是处理这类问题最标准、最有效的方式。