跟他学sql(第二天)

前言

那么今天我们来学sql。

第七问

题目:查询学过编号为01的课程也学过编号为02课程的学生的学号、姓名。
分析:

  • 课程号c_id
  • 学号s_id
  • 学生姓名s_name

学号和姓名在一张表中,学号和课程号在一张表中。
我们把问题拆成两个子问题:

  • 编号为01的课程也学过编号为02课程的学生的学号
  • 学号对应的姓名

对于第一个问题,我们把表score分别筛选出c_id = 01c_id = 02的字段然后自联得到视图v1。
然后通过视图v1查询出学生姓名有两种方法,学生表和v1连接以及学生表s_id in v1,那么我们最后得出结果:

select s1.s_id,s1.s_name from Student s1
where s1.s_id in
(
	//注意这边,连表之后的表要进行查询操作才能得到对应的视图
	select s2.s_id from
	(
		(select s_id from score where c_id = '01') s2
		join
		(select s_id from score where c_id = '02') s3
		on s2.s_id = s3.s_id
	)
)

第七问结果


第八问

题目:查询课程编号为02的总成绩
分析:

  • 课程编号c_id
  • 总成绩SUM(score)

那么使用表score就可以实现,注意使用having筛选而非where

select SUM(s_score) from score
GROUP BY c_id
HAVING c_id = '02'

第八问


第九问

问题:查询所有课程成绩小于60分的学生的学号和姓名
分析:
其实这个问题存在歧义,到底是所有课程小于60分的所有学生还是任意一门课程小于60分的所有学生。
那我这边假设是前者。

  • 学号s_id
  • 姓名s_name
  • 所有成绩小于60max(s_score)<60
SELECT s1.s_id,s1.s_name FROM Student s1
JOIN
(SELECT s_id FROM score GROUP BY s_id HAVING MAX(s_score)<60) s2
on s1.s_id = s2.s_id

第九问结果


第十问

题目:查询没有学全所有课的学生的学号和姓名
分析:又是所有课,所以我们采用和之前一样的方法,计算出总的课程数count_c,然后找出所有score表中记录数小于count_c的学生(要使用group by聚类,所以又是使用having),然后再获得其姓名。

  • 学号s_id
  • 姓名s_name
  • 课程号c_id
  • 课程数 select count(*) from course
SELECT s1.s_id,s1.s_name FROM Student s1
JOIN
(SELECT s_id FROM score GROUP BY s_id HAVING COUNT(c_id) < (SELECT COUNT(*) FROM course)) s2
ON s1.s_id = s2.s_id

第十问结果


第十一问

题目:查询至少有一门课与学号为“01”的学生所学课程相同的学生的学号和姓名
分析:
看到至少有一门,那么我们很容易想到取反,就是说,先找到和01学生一门课都不同的学生再取反(这里要使用and s_id != 01来排除学生自己)。
那么如何找到一门课都不相同呢?
先查询出01学生学过的所有课程,然后使用not in字段来获取课程号不同于这些课程的行。

  • 学号s_id
  • 课程号c_id
  • 姓名s_name
SELECT s_id,s_name FROM Student
WHERE s_id NOT IN 
(SELECT s_id FROM score WHERE c_id NOT IN(SELECT c_id FROM score WHERE s_id = '01'))
AND s_id != '01'

第十一问结果


在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_33241802/article/details/106877941