医药数据库学习第三章实战(3)

由于上一篇的篇幅过长,所以实战我直接单独演练吧。
o对了,mysql里面的字符最好都用单引号,否则也许会出错!

课本习题

假设有一个学生选课的数据库,它包含三个关系模式:

student

sno sname sex birth specialty
20101140101 张三 1992-06-01 CS
20101140102 李四 1991-09-23 IS
20101140103 王五 1992-05-04 CS
20101140104 李徜徉 1992-08-09 MI

course

cno cname credit category
001 C程序设计 5 必修
002 数据库系统理论 4 必修
003 ORACLE基础 3 选修

sc

sno cno grade
20101140101 001 85
20101140101 002 78
20101140101 003 90
20101140102 001 87
20101140102 002 89

请完成以下练习:
1)用SQL语言完成上述数据库的三张表的定义,包括主码,外码及自定义约束
2)完成每张表的记录录入
3)查询1992年出生的学生的基本信息
4)查询姓“李”的学生
5)查询不是“CS”和“MA”专业的学生的学号和姓名
6)查询“001”号课程的平均成绩
7)查询年龄最大的学生的学号和姓名
8)查询每个学生所选课程的平均成绩
9)查询“CS”专业的男生信息
10)查询与“王五”在用一个专业学习的基本信息(用自然连接查询和嵌套查询两种方式实现)
11)查询每个学生超过他选修课程平均成绩的课程号
12)查询每个学生以及其选修课程情况(要求用左外连接实现)
13)查询至少选修了“001”和“002”号课程的学生的学号
14)将“002”课程的名称改为“数据库系统原理及应用”
15)删除“李四”的选课记录
16)假设“王五”选修了所有的三门课程,将“王五”的学号及其选修的三门课程号(“001”,“002”,“003”)一次插入SC表
17)创建学生选课的视图S_C,包括学号,姓名,课程号,课程名称,成绩
18)在视图S_C基础上,查询学生“张三”的选课情况

1)首先,我们通过例如以下代码将表建好
在这里插入图片描述2)数据录入OK
在这里插入图片描述

3)
分析:若要查询一个1992年出生的人员姓名,我们可以从这句话中提取出部分信息:①需要student.birth列作为查询依据②需要整个student表数据。所以我们发现,这两个需要的信息都在同一张表中,那岂不是很好办了么?

select *
from study.student
where student.birth like '1992%';

这样我们就查询正确了!

在这里插入图片描述

4)
分析:查询姓“李”的学生,那和上一题有异曲同工之处,只是输出我们可以改成只输出student.sname这一列

select student.sname
from student
where student.sname like '李%';

在这里插入图片描述

5)
分析:查询不是“CS”和“MA”专业的学生的学号和姓名,这也好办,直接把where条件改成not like and就ok了

select student.sno,student.sname
from student
where student.specialty not like 'CS' or 'MA';

当然你也可以这么写,因为这是个逻辑问题

select student.sno,student.sname
from student
where (student.specialty not like 'CS') and (student.specialty not like 'MA');
select student.sno,student.sname
from student
where student.specialty not in ('CS','MA');

答案依旧

在这里插入图片描述

6)
注意!注意!若使用外键时,主键拥有的数据,外键才能引用,如果外键随便添加主键不存在的数据是无效的!
查询“001”号课程的平均成绩,接下来是有了点难度的了,因为要调用到函数了。首先我们分析一下:要对001课程的选课学生的成绩进行AVG运算,然后看看要选择什么输出什么:①选择sc.cno中值等于’001’的行②对这些行的同表格的sc.grade列的值进行AVG计算,然后输出

select avg(sc.grade)
from sc
where sc.cno='001';

在这里插入图片描述

你也可以取个别名好看点

在这里插入图片描述

7)
查询年龄最大的学生的学号和姓名,这一看就需要用到聚集函数,思路:①找到student.birth中最小的学生②查询输出出他的学号与姓名
由于聚集函数只能在select和group中书写,而我们又不想输出这个列,所以我们用了嵌套查询来实现

select student.sno, student.sname
from student
where student.birth = (
    select min(student.birth)
    from student
);

在这里插入图片描述

8)
查询每个学生所选课程的平均成绩,说明输出是sc.sno和sc.grade,因此可以①先对sc.sno进行分组,②然后每组的sc.grade进行avg,③最终的结果再和sc.sno拼接

select sc.sno, avg(sc.grade) avg
from sc
group by sc.sno
having avg(sc.grade);

在这里插入图片描述

9)
查询“CS”专业的男生信息,那就在student.specialty选中CS的并且student.sex是男的然后输出他们的这表的所有信息

select *
from student
where student.specialty='CS' and student.sex='男';

10)
查询与“王五”在同一个专业学习的基本信息(用自然连接查询和嵌套查询两种方式实现),选出与王五的specialty相等的行,

自然连接


嵌套查询

select distinct *
from student
where student.sname != '王五'
  and student.specialty = (
    select student.specialty
    from student
    where student.sname = '王五'
);

在这里插入图片描述

11)
查询每个学生超过他选修课程平均成绩的课程号,①输出学号与课程号②sc.grade>avg(sc.grade)③
典型的自身连接+嵌套

select distinct first.sno, first.cno
from sc first
where first.grade >= (
    select avg(second.grade)
    from sc second
    where second.sno = first.sno
)

在这里插入图片描述

12)
查询每个学生以及其选修课程情况(要求用左外连接实现),来一个left join,没有where语句的

select distinct student.*,sc.cno
from student left join sc on student.sno = sc.sno;

在这里插入图片描述

13)
查询至少选修了“001”和“002”号课程的学生的学号,至少选修001,002,需要输出学生学号,需要用 存在 、联合 函数来设置2个规定条件

select x.sno
from sc x
group by x.sno
having count(x.cno) >= 2
and exists(
    select y.sno
    from sc y
    where y.cno='001'
    union
    select y.sno
    from sc y
    where y.cno='002'
    )

14)
将“002”课程的名称改为“数据库系统原理及应用”,用update函数

UPDATE study.course t SET t.cname = '数据库系统原理及应用' WHERE t.cno = '002';

15)
删除“李四”的选课记录,诶,我们也可以用删除嵌套查询语句

delete from sc where sc.sno=(
    select student.sno
    from student
    where sname='李四'
    );

16)
假设“王五”选修了所有的三门课程,将“王五”的学号及其选修的三门课程号(“001”,“002”,“003”)一次插入SC表,用逗号分割

insert into study.sc
values ('20101140103', '001', null),
       ('20101140103', '002', null),
       ('20101140103', '003', null);

17)
创建学生选课的视图S_C,包括学号,姓名,课程号,课程名称,成绩

create view study.S_C as
select student.sno, student.sname, sc.cno, course.cname, sc.grade
from sc,
     student,
     course
where student.sno=sc.sno and sc.cno=course.cno;

在这里插入图片描述

18)
在视图S_C基础上,查询学生“张三”的选课情况

select s_c.sname,s_c.cname
from s_c
where s_c.sname='张三';

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_52480906/article/details/121217048