70 分钟上机练习:子查询与 UNION

这一份页面只包含:上机数据准备、练习题目、解题提示。不放参考答案,适合直接投给学生作为练习页使用。

练习目标
  • 把单值子查询、多值子查询、相关子查询、EXISTS / NOT EXISTS 这几类写法真正写一遍
  • 把 UNION 与连接查询区分开,能独立完成结果合并题
  • 通过一题综合题,串起“子查询 + UNION”的组合使用
建议节奏
  • 数据导入:5 分钟
  • 第 1-6 题:41 分钟
  • 第 7-10 题:29 分钟
题目页 不含答案 含模拟数据 适合单次上机
练习说明

这套练习围绕两个小章节的重点:6.3 子查询6.4 集合运算查询。题目按从易到难安排,先写基础题,再写综合题。若某题写完后不确定是否正确,可以先执行,再观察结果是否符合题意。

10
练习题
10
题目总数
70 分钟
建议总时长
2 类重点
子查询 / UNION

一、上机前先导入模拟数据

先执行下面这一段建表与插入数据的 SQL。后面的练习都默认基于这组数据完成。

SQL
DROP TABLE IF EXISTS tc; DROP TABLE IF EXISTS sc; DROP TABLE IF EXISTS t; DROP TABLE IF EXISTS c; DROP TABLE IF EXISTS s; CREATE TABLE s ( sno VARCHAR(10) PRIMARY KEY, sn VARCHAR(20) NOT NULL, age INT, maj VARCHAR(20) ); CREATE TABLE c ( cno VARCHAR(10) PRIMARY KEY, cn VARCHAR(30) NOT NULL, ct INT ); CREATE TABLE t ( tno VARCHAR(10) PRIMARY KEY, tn VARCHAR(20) NOT NULL, prof VARCHAR(20), maj VARCHAR(20), dept VARCHAR(30), sal INT ); CREATE TABLE sc ( sno VARCHAR(10), cno VARCHAR(10), score INT ); CREATE TABLE tc ( tno VARCHAR(10), cno VARCHAR(10), tcdate DATE ); INSERT INTO s VALUES ('s1','张三',18,'计算机'), ('s2','赵琳琳',19,'数学'), ('s3','王敏',20,'计算机'), ('s4','陈晨',21,'英语'), ('s5','李雪',18,'数学'), ('s6','周楠',22,'计算机'); INSERT INTO c VALUES ('c1','程序设计基础',64), ('c2','数据库原理',48), ('c3','高等数学',56), ('c4','Web前端开发',64), ('c5','大学英语',32); INSERT INTO t VALUES ('t1','顾伟','副教授','计算机','计算机学院',5200), ('t2','李明','讲师','数学','数学学院',5600), ('t3','王华','教授','计算机','计算机学院',6800), ('t4','刘芳','讲师','英语','外国语学院',7000), ('t5','周强','副教授','计算机','计算机学院',6100), ('t6','陈刚','副教授','化学','化学学院',6300); INSERT INTO sc VALUES ('s1','c1',86), ('s1','c2',90), ('s2','c1',88), ('s2','c2',92), ('s3','c3',85), ('s3','c1',79), ('s4','c2',69), ('s4','c5',80), ('s5','c3',91), ('s5','c2',84), ('s6','c1',95), ('s6','c4',89); INSERT INTO tc VALUES ('t1','c1','2024-09-01'), ('t1','c2','2024-09-01'), ('t2','c3','2024-09-02'), ('t3','c1','2025-02-20'), ('t4','c5','2024-09-05'), ('t5','c4','2024-09-10');
导入后建议先自检:可以执行 SELECT * FROM s;SELECT * FROM c;SELECT * FROM sc; 看看数据是否已经成功写入。
这组数据里包含哪些表
表名作用关键字段
s学生表sno, sn, age, maj
c课程表cno, cn, ct
t教师表tno, tn, maj, sal
sc选课表sno, cno, score
tc授课表tno, cno, tcdate

二、必做练习题

1
单值子查询:比赵琳琳年龄大的学生
6 分钟

要求:查询比学生“赵琳琳”年龄大的学号、姓名和年龄。

提示:
  • 先想清楚:题目里真正要拿来比较的值是什么。
  • 子查询应该先从学生表中查出“赵琳琳”的年龄。
  • 外层再使用 > 进行比较。
2
多值子查询:查询 s2 选修的课程信息
7 分钟

要求:查询学号为 s2 的学生选修的课程号、课程名和课时。

提示:
  • 先从 sc 表中找到 s2 对应的一组课程号。
  • 再去课程表 c 中把这些课程号对应的课程名与课时取出来。
  • 本题建议使用 IN。
3
多值子查询:比计算机专业所有教师工资都高
8 分钟

要求:查询其他专业中,比“计算机”专业所有教师工资都高的教师号、姓名、专业和工资。

提示:
  • “比所有教师都高”对应的是 ALL。
  • 也可以先想它与 MAX 的关系。
  • 别忘记排除 maj = 计算机 的教师。
4
相关子查询:查询选修 c1 的学生
7 分钟

要求:使用相关子查询,查询选修了课程号为 c1 的学号和姓名。

提示:
  • 外层表是学生表 s。
  • 内层表是选课表 sc。
  • 关键是把父查询当前行中的 s.sno 带入子查询。
5
NOT EXISTS:查询没有选修 c1 的学生
7 分钟

要求:使用 NOT EXISTS,查询没有选修课程号为 c1 的学号和姓名。

提示:
  • 本题与上一题思路接近,只是判断方向相反。
  • EXISTS / NOT EXISTS 关心的是有没有记录,而不是返回什么具体值。
6
EXISTS:查询 t1 教授的课程信息
6 分钟

要求:使用 EXISTS,查询教师号为 t1 的教师讲授的课程号、课程名和课时。

提示:
  • 最终要输出课程号、课程名、课时,所以外层表应选课程表 c。
  • 子查询用 tc 表判断当前课程是否由 t1 讲授。
7
UNION:合并两个专业的学生信息
5 分钟

要求:查询“计算机”专业学生的学号、姓名、专业,再查询“数学”专业学生的学号、姓名、专业,并用 UNION 合并结果。

提示:
  • 两边 SELECT 返回的列数和顺序必须一致。
  • 本题是把两个结果上下合并,不是连接表。
8
UNION:合并两门课程的统计结果
8 分钟

要求:分别统计 c1 和 c2 的总分、平均分,并用 UNION 合并成一个结果集。结果列名要求为:课程号、总分、平均分。

提示:
  • 每一边都要先 GROUP BY cno。
  • 两边返回列结构必须完全对应。
  • 建议给字段加别名。
9
UNION 去重观察题
7 分钟

要求:查询“计算机”专业学生的学号和姓名,再查询年龄大于等于 20 岁学生的学号和姓名,使用 UNION 合并,并观察结果中是否有重复行。

提示:
  • 先写出两个 SELECT,再用 UNION 连接。
  • 重点观察同时满足两个条件的学生,最终会不会出现两次。
10
综合题:子查询 + UNION
9 分钟

要求:先查询“没有选修 c1 课程”的学生的学号、姓名、专业;再查询“英语专业”的学生的学号、姓名、专业;最后用 UNION 合并成一个结果集。

提示:
  • 前半部分可以使用 NOT EXISTS,也可以使用 NOT IN。
  • 后半部分是普通条件筛选。
  • 注意两边列结构要一致,且 UNION 会自动去重。

四、完成检查

写完后可以按下面顺序快速自检:

检查点说明
子查询方向对不对先问自己:内层是在查一个值,还是一组值,还是只判断有没有记录。
UNION 两边结构是否一致列数、列顺序、列含义尽量一致,否则容易报错或结果混乱。
结果是否符合题意不要只看“能运行”,还要看返回的记录是不是题目真正要的。
是否误把 UNION 写成 JOIN合并结果用 UNION;跨表按字段关联用 JOIN。
提醒:题目页不包含参考答案。若需要核对 SQL 与结果,请打开单独的答案详解页。