山东大学 2020级数据库系统 实验五

What’s more

山东大学 2020级数据库系统 实验一
山东大学 2020级数据库系统 实验二
山东大学 2020级数据库系统 实验三
山东大学 2020级数据库系统 实验四
山东大学 2020级数据库系统 实验五
山东大学 2020级数据库系统 实验六
山东大学 2020级数据库系统 实验七
山东大学 2020级数据库系统 实验八、九

写在前面

做数据库实验一定要静得下心来,才能发现其中的错误然后进行改正。同时,如果发现 SQL 语句总是报错,“一定是你错了,只是不知道错在哪里!”

其次,SQL 语句中较为复杂的点博主都进行了注释,希望大家一定要看懂思路后自己写一遍,而不是盲目的 Ctrl+C,Ctrl+V,切记切记!!

实验五

实验五主要考察的内容如下:
对于聚集函数 sum, max, count 的使用,同时有无 group by 的意识;

对于分部分查询的熟练程度;(可能会有其他方法,但这部分我分块查询用的比较多~~

对于 union all 的了解及区分 union all 和 union 的区别;

  • 5-1 在学生表pub.student中统计名字(姓名的第一位是姓氏,其余为名字,不考虑复姓)的使用的频率,将统计结果放入test5_01中,表结构如下。
    First_name varchar(4) frequency numeric(4)
    国强 1034
    红 1232
    卫东 2323
    ………………

    思路:
    1. 使用 substr() 函数取出名字中的姓;
    2. 然后对所有姓进行 count 计数即可
create table test5_01 asselect distinct substr(name, 2, length(name)) first_name, count(*) frequencyfrom pub.studentgroup by substr(name, 2, length(name))
  • 5-2 在学生表pub.student中统计名字(姓名的第一位是姓氏,不作统计,名字指姓名的第二个之后的汉字)的每个字使用的频率,将统计结果放入test5_02中(特别提示:需要区别union和union all的不同),表结构如下。
    letter varchar(2) frequency numeric(4)
    锋 1034
    红 1232
    鹏 2323
    ………………

    避坑指南:

    1. 需要先选出姓名中的第二个字和第三个字,然后再对他们进行统一的计数;

    思路:
    1. 选出名字中的第二个字,记为集合 A,然后使用 union all 来连接名字中第三个字的集合,记为B;(union 和 union all 的区别在于一个去重,一个不去重)
    2. 然后对 A ∪\cup B 进行统一的计数即可;

create table test5_02(letter varchar(2),frequency numeric(4))
insert into test5_02
select letter, count(*) frequency
from ((select substr(name, 2, 1) letterfrom pub.studentwhere substr(name, 2, 1) is not null)union all(select substr(name, 3, 1) letterfrom pub.studentwhere substr(name, 3, 1) is not null))
group by letter
  • 5-3 创建"学院班级学分达标情况统计表1"test5_03,依据pub.student, pub.course,pub.student_course统计形成表中各项数据,成绩>=60为及格计入学分,总学分>=10算作达标,院系为空值的数据不统计在下表中,表结构:院系名称dname、班级class、学分达标人数p_count1、学分未达标人数p_count2、总人数p_count。
    Dname varchar(30) class varchar(10) P_count1 Int P_count2 int P_count int
    计算机学院 2006
    计算机学院 2007
    软件学院 2006
    ………………

    注意:此题较难,如果你现在静不下来,那就下下道题吧;如果能够静下来,Let’s go
    避坑指南:

    1. “成绩 >= 60” 是指该学生该门课的成绩的最大值 >= 60;(可能有考了多次的学生)
    2. 有的学生在 pub.student 中,但是他没有选课,因此又不在 pub.student_course 中。这部分学生应该算作学分未达标 p_count2。因此,这部分这么难算,为何不用 p_count - p_count1 呢?(我也给出计算 p_count2 的代码啦,有兴趣可以看看~~)
    3. 有的学院班级的学生全部都学分不达标;(其实只有一个‘生命科学学院 2008’,帮忙就帮到这儿啦,具体人数还是自己算一算哈~~)当时卡了我好久/(ㄒoㄒ)/~~

    思路:(分块查询)

    1. 先从 pub.student 中选出 dname, class, p_count,结果记为 t1;
    2. 再从 t2 表中找到 p_count1:需要先找到每个学生每门课的最高分,在通过最高分判定是否得到相应的学分,再用 sum(credit) 来得到学分的和,最后进行判定;
    3. p_count2 使用 p_count - p_count1 即可;
create table test5_03(dname varchar(30),class varchar(10),p_count1 int,p_count2 int,p_count int)
-----------一张表一张表地看思路更清晰哦(一共就 t1,t2 两张表)--------------
insert into test5_03
select t1.dname, t1.class, t2.p_count1, (t1.p_count - t2.p_count1) p_count2, t1.p_count
from (select distinct dname, class, count(*) p_countfrom pub.studentwhere dname is not nullgroup by dname, class) t1,					--t1 表:找到 dname, class, p_count(select distinct dname, class, count(*) p_count1from (select sid, dname, class, sum(credit) sum_credit	--找到总学分from (select sid, cid, dname, class, max(score) max_score	--找到成绩的最大值from pub.student_course natural join pub.studentgroup by sid, cid, dname, class) natural join pub.coursewhere max_score >= 60					--最大成绩 >= 60 才计入学分and dname is not nullgroup by sid, dname, class)where sum_credit >= 10						--总学分 > 10 才选出来group by dname, class) t2,					--t2 表:找到 p_count1(找 dname 和 class 是为了在后面进行连接)where t1.dname = t2.dname
and t1.class = t2.class

现在给出计算 p_count2 的代码,有兴趣可以看看哈~~

select distinct dname, class, count(*) p_count2
from ((select sid, dname, class, sum(credit) sum_credit		--选了课但是没有达标的学生from (select sid, cid, dname, class, max(score) max_scorefrom pub.student_course natural join pub.studentgroup by sid, cid, dname, class) natural join pub.coursewhere max_score >= 60and dname is not nullgroup by sid, dname, class)
union(select distinct sid, dname, class, 0 as sum_credit		--在 pub.student 中但是不在 pub.student_course 中的学生,这部分学生也算作不达标哦~~from pub.studentwhere sid not in(select sidfrom pub.student_course)))
where sum_credit < 10
group by dname, class
  • 5-4 创建"学院班级学分达标情况统计表2"test5_04,依据pub.student, pub.course,pub.student_course统计形成表中各项数据,成绩>=60为及格计入学分,2008级及之前的班级总学分>=8算作达标,2008级之后的班级学分>=10算作达标,院系为空值的数据不统计在下表中,表结构:院系名称dname、班级class、学分达标人数p_count1、学分未达标人数p_count2、总人数p_count。
    Dname varchar(30) class varchar(10) P_count1 int P_count2 int P_count int
    计算机学院 2006
    计算机学院 2007
    软件学院 2006
    ………………

    思路:
    1. 如果你看懂了 5-3 的思路,那么相信这道题对你来说会比较简单。只需要改变一下条件,增加一个判定即可;
create table test5_04(dname varchar(30),class varchar(10),p_count1 int,p_count2 int,p_count int)
-----------一张表一张表地看思路更清晰哦(一共就 t1,t2 两张表)--------------
insert into test5_04
select t1.dname, t1.class, t2.p_count1, (t1.p_count - t2.p_count1) p_count2, t1.p_count
from (select distinct dname, class, count(*) p_countfrom pub.studentwhere dname is not nullgroup by dname, class) t1,(select distinct dname, class, count(*) p_count1from (select sid, dname, class, sum(credit) sum_creditfrom (select sid, cid, dname, class, max(score) max_scorefrom pub.student_course natural join pub.studentgroup by sid, cid, dname, class) natural join pub.coursewhere max_score >= 60and dname is not nullgroup by sid, dname, class)where sum_credit >= 					--Look at here! 增加的条件在这里 —— 就是根据 class 来决定 sum_credit 的判定条件哦casewhen class <= 2008 then 8when class > 2008 then 10endgroup by dname, class) t2where t1.dname = t2.dname
and t1.class = t2.class

手动算 p_count2 也是在相同的地方加上 case 即可。

  • 5-5 注意事项:
    如果一个学生一门课程有多次成绩,仅仅计算最高成绩,也就是只用他的最好成绩参加如下统计。
    5. 查询各院系(不包括院系名称为空的)的数据结构平均成绩avg_ds_score、操作系统平均成绩avg_os_score,平均成绩四舍五入到个位,创建表test5_05,表结构及格式如下:
    Dname Avg_ds_score Avg_os_score
    马克思主义学院 72 70
    软件学院 77 74
    艺术学院 77 76
    医学院 74 73

    思路:
    1. 主要还是运用了分块查询的思想;
    2. 先从 t1 表中找到唯一的 dname 属性值;
    3. 然后从 t2 表中找到“数据结构”课程成绩的平均值;(注意其中包含了一个求最大值的过程)
    4. 同样,接着从 t2 表中找到“操作系统”课程成绩的平均值;(也有一个求最大值的过程)
    5. 最后使用 dname 来进行连接即可;(或者直接 natural join 也行)
create table test5_05(dname varchar(20),avg_ds_score int,avg_os_score int);
insert into test5_05
select distinct t1.dname, t2.avg_ds_score, t3.avg_os_score
from(select distinct dnamefrom pub.student) t1,(select distinct dname, round(avg_ds_score, 0) avg_ds_scorefrom (select distinct dname, avg(max_ds_score) avg_ds_scorefrom (select distinct sid, dname, max(score) max_ds_scorefrom pub.student natural join pub.student_coursewhere cid = (select cid from pub.course where name = '数据结构')group by sid, dname)group by dname)) t2,(select distinct dname, round(avg_os_score, 0) avg_os_scorefrom (select distinct dname, avg(max_os_score) avg_os_scorefrom (select distinct sid, dname, max(score) max_os_scorefrom pub.student natural join pub.student_coursewhere cid = (select cid from pub.course where name = '操作系统')group by sid, dname)group by dname)) t3
where t1.dname = t2.dname
and t2.dname = t3.dname
  • 5-6 查询"计算机科学与技术学院"的同时选修了数据结构、操作系统两门课的学生的学号sid、姓名name、院系名称dname、数据结构成绩ds_score、操作系统成绩os_score,创建表test5_06。
    思路:
    1. 分块查询:先找到同时选了这两门课的学生的 sid, name,在分别找这两门课的成绩;
    2. 使用存在性检测 not exists … except(minus) … 结构可以找到同时选修了这两门课的学生的 sid, name;
    3. 需要注意的是:这两门课的成绩都需要用对应成绩的最大值哦~~
create table test5_06 asselect t1.sid, t1.name, '计算机科学与技术学院' as dname, t2.ds_score, t3.os_scorefrom (select sid, namefrom pub.student Swhere dname = '计算机科学与技术学院'and not exists(	(select cidfrom pub.coursewhere name = '数据结构' or name = '操作系统')minus(select cidfrom pub.student_course Twhere S.sid = T.sid))) t1,(select sid, max(score) ds_scorefrom pub.student_coursewhere cid = (select cid from pub.course where name = '数据结构')group by sid) t2,(select sid, max(score) os_scorefrom pub.student_coursewhere cid = (select cid from pub.course where name = '操作系统')group by sid) t3where t1.sid = t2.sidand t2.sid = t3.sid
  • 5-7 查询计算机科学与技术学院的选修了数据结构或者操作系统的学生的学号sid、姓名name、院系名称dname、数据结构成绩ds_score、操作系统成绩os_score,创建表test5_07。
    思路:
    1. 先去找到计算机科学与技术学院选修了“数据结构”或者“操作系统”的学生的 sid, name;
    2. 由于二者只修其一的学生我们同样需要将它保留下来,因此可以使用 natural left outer join来连接成绩;
    3. 这两门课的成绩同样注意使用最大值即可;
create table test5_07 asselect sid, name, dname, ds_score, os_scorefrom (select distinct sid, name, dnamefrom pub.student natural join pub.student_coursewhere dname = '计算机科学与技术学院'and cid in (select cid from pub.course where name = '数据结构' or name = '操作系统')) natural left outer join (select distinct sid, max(score) ds_scorefrom pub.student_course natural join pub.coursewhere name = '数据结构'group by sid)natural left outer join(select distinct sid, max(score) os_scorefrom pub.student_course natural join pub.coursewhere name = '操作系统'group by sid)
  • 5-8 查询计算机科学与技术学院所有学生的学号sid、姓名name、院系名称dname、数据结构成绩ds_score、操作系统成绩os_score,创建表test5_08。
    思路:
    1. 直接找到计算机科学与技术学院所有学生的 sid, name;
    2. 接着找到每门课成绩的最大值;
    3. 最后使用 natural left outer join 即可;
create table test5_08 asselect sid, name, dname, ds_score, os_scorefrom (select distinct sid, name, dnamefrom pub.studentwhere dname = '计算机科学与技术学院') natural left outer join (select distinct sid, max(score) ds_scorefrom pub.student_course natural join pub.coursewhere name = '数据结构'group by sid)natural left outer join(select distinct sid, max(score) os_scorefrom pub.student_course natural join pub.coursewhere name = '操作系统'group by sid)

再次强调:一定是看懂思路之后自己实践哈~~
有问题还请斧正!

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/565088.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言二维数组的使用

二维数组的定义 二维数组定义的一般形式是&#xff1a; dataType arrayName[length1][length2];其中&#xff0c;dataType 为数据类型&#xff0c;arrayName 为数组名&#xff0c;length1 为第一维下标的长度&#xff0c;length2 为第二维下标的长度。 我们可以将二维数组看…

python基础入门(8)之集合

目录 Python集合 一、集合理解 二、访问集合 2.1&#xff09;遍历集合 3.2&#xff09;检查是否存在 三、添加集合 3.1&#xff09;添加项目值 3.3&#xff09;添加任何可迭代对象 四、移除集合项 4.1&#xff09;remove方法 4.2&#xff09;iscard() 方法 4.3&…

山东大学 2020级数据库系统 实验六

What’s more 山东大学 2020级数据库系统 实验一 山东大学 2020级数据库系统 实验二 山东大学 2020级数据库系统 实验三 山东大学 2020级数据库系统 实验四 山东大学 2020级数据库系统 实验五 山东大学 2020级数据库系统 实验六 山东大学 2020级数据库系统 实验七 山东大学 20…

C语言数组元素的查询

数组的查询 在日常的开发过程中&#xff0c;我们经常需要查询数组中的元素&#xff0c;这就需要我们使用数组元素查询的方法来进行查询。 对无序数组的查询 无序数组&#xff0c;就是数组元素的排列没有规律。无序数组元素查询的思路也很简单&#xff0c;就是用循环遍历数组…

山东大学 2020级数据库系统 实验七

What’s more 山东大学 2020级数据库系统 实验一 山东大学 2020级数据库系统 实验二 山东大学 2020级数据库系统 实验三 山东大学 2020级数据库系统 实验四 山东大学 2020级数据库系统 实验五 山东大学 2020级数据库系统 实验六 山东大学 2020级数据库系统 实验七 山东大学 20…

python基础入门(9)之字典

目录 Python字典 一、字典理解 1.1&#xff09;创建字典与访问 1.2&#xff09;字典长度 1.3&#xff09;数据类型 二、访问字典 2.1&#xff09;访问键名 2.2&#xff09;访问健值 三、更改字典各种方法 四、添加字典项各种方法 五、删除字典的各种方法 ​六、遍历…

山东大学 2020级数据库系统 实验八、九

What’s more 山东大学 2020级数据库系统 实验一 山东大学 2020级数据库系统 实验二 山东大学 2020级数据库系统 实验三 山东大学 2020级数据库系统 实验四 山东大学 2020级数据库系统 实验五 山东大学 2020级数据库系统 实验六 山东大学 2020级数据库系统 实验七 山东大学 20…

python基础入门(10)之循环语句

目录 一、If … Else语句 一.if语句 二.缩进 三.elif语句 四.else语句 4.1基本else 4.2&#xff09;and语句 4.3&#xff09;or 语句 4.4&#xff09;嵌套if语句 4.4&#xff09;pass语句 二、while循环语句 一.基本理解 二.中断声明 三.continue 声明 四.else …

python基础(11)之函数

目录 函数 一、创建函数与调用 二、参数 三、参数数量 四、任意参数&#xff0c;*args 五、关键字参数 七、任意关键字参数&#xff0c;**kwargs 八、默认参数值 九、将列表作为参数传递 十、返回值 十一、pass语句 函数 一、创建函数与调用 在 Python 中&#xf…

排序算法的实现及时间复杂度分析——计数排序、选择排序、冒泡排序、插入排序

文章目录排序算法计数排序选择排序冒泡排序插入排序排序算法 排序算法是解决问题中常见且非常重要的一环&#xff0c;针对相应的问题选择相应的排序算法&#xff0c;能够提高问题解决速度&#xff0c;节省时间&#xff01;&#xff01;&#xff01; 常见的排序算法有&#xf…

python基础(12)之匿名函数lambda

lambda lambda 函数是一个小的匿名函数。一个 lambda 函数可以接受任意数量的参数&#xff0c;但只能有一个表达式。 语法&#xff1a; lambda arguments : expression 执行表达式并返回结果&#xff1a; 示例将 10 添加到 argument a&#xff0c;并返回结果&#xff1a; …

C语言快速排序

快速排序是对冒泡法排序的一种改进。 快速排序算法 的基本思想是&#xff1a;将所要进行排序的数分为左右两个部分&#xff0c;其中一部分的所有数据都比另外一 部分的数据小&#xff0c;然后将所分得的两部分数据进行同样的划分&#xff0c;重复执行以上的划分操作&#xff0…

机器学习入门(1)之基本概念简介

目录 一、机器学习概述 1.1 什么是机器学习&#xff1f; 1.2 为什么需要机器学习&#xff1f; 1.3 机器学习应用场景 1.4 机器学习的一般流程 1.5 典型的机器学习过程​ 二、机器学习的基本术语 三.假设空间与版本空间 四、归纳偏好 1.哪种更好 2..假设的选择原则 …

山东大学 2020级计算机系统原理——拆解二进制炸弹

写在前面 第一次拿到这个实验还是有点慌&#xff01;之前没见过&#xff0c;不过还是慢慢做过来了。 这是个需要耐心的过程&#xff0c;请一定静下心来哦&#xff01; 环境及配置 环境&#xff1a;Ubuntu 20.04 GDB 调试工具 可参考配置&#xff1a;GDB调试工具配置&#…

机器学习入门(2)之模型评估与选择

目录 一、误差与拟合 1. 泛化误差与经验误差 2. 损失函数与训练误差 3. 过拟合与欠拟合 4. 过拟合的另一种现象&#xff1a;数据泄露 二、评估方法 1. 留出法 2. 交叉验证法&#xff08;留一法&#xff09; 3. 自助法 4. 调参与最终模型 三、性能度量 1. 混淆矩阵 …

pytorch MNIST 手写数字识别 + 使用自己的测试集 + 数据增强后再训练

文章目录1. MNIST 手写数字识别2. 聚焦数据集扩充后的模型训练3. pytorch 手写数字识别基本实现3.1完整代码及 MNIST 测试集测试结果3.1.1代码3.1.2 MNIST 测试集测试结果3.2 使用自己的图片进行测试3.2.1 测试图片预处理代码3.2.2 测试图片结果4. 数据增强4.1 手动读取 MNIST …

python基础(13)之数组

目录 数组 一、访问数组的元素 二、数组的长度 三、修改数组 四、数组的其它操作 数组 Python 没有对数组的内置支持&#xff0c;但可以使用Python 列表代替。 例如&#xff1a; ben ["笨小孩1", "笨小孩2", "笨小孩3"]一、访问数组的元…

C语言归并排序(合并排序)

归并排序也称合并排序&#xff0c;其算法思想是将待排序序列分为两部分&#xff0c;依次对分得的两个部分再次使用归并排序&#xff0c;之后再对其进行合并。仅从算法思想上了解归并排序会觉得很抽象&#xff0c;接下来就以对序列A[0], A[l]…, A[n-1]进行升序排列来进行解说&a…

python基础(14)之 类和对象

目录 Python类和对象 一、创建类 二、创建对象 三、init() 函数 四、对象方法 五、自参数 六、对象及其属性更改 七、pass语句 Python类和对象 Python 类/对象。Python 是一种面向对象的编程语言。Python 中的几乎所有东西都是一个对象&#xff0c;有它的属性和方法。…

C语言顺序查找

顺序査找是一种简单的査找算法&#xff0c;其实现方法是从序列的起始元素开始&#xff0c;逐个将序列中的元素与所要查找的元素进行比较&#xff0c;如果序列中有元素与所要查找的元素相等&#xff0c;那么査找成功&#xff0c;如果査找到序列的最后一个元素都不存在一个元素与…