数据库SQL语言实战(七)

前言

这次的有一点点难~~~~~我也写了好久

练习题

题目一

在学生表pub.student中统计名字(姓名的第一位是姓氏,其余为名字,不考虑复姓)的使用的频率,将统计结果放入表test5_01中

create table test5_01(First_name varchar(4),frequency numeric(4)
)
insert into test5_01(select substr(name,2),count(*)from pub.studentgroup by substr(name,2)
)

 关键点:

1、substr(‘name’,start_position,[length]):name表示列名;start_positon表示开始位置(不同于其他语言,SQL的下标从1开始);length表示长度(可写可不写,不写表示取到最后)

2、insert into table_name values():单行具体量插入

3、insert all

     into table_name values()

     into table_name values()

     select * from dual:多行具体量插入

4、insert into table_name(

                select 选择语句

      ):select实现批量插入操作

题目二

在学生表pub.student中统计名字(姓名的第一位是姓氏,不作统计,名字指姓名的第二个之后的汉字)的每个字使用的频率,将统计结果放入表test5_02中,表结构如下。

create table test5_02(letter varchar(4),frequency numeric(4)
)
insert into test5_02(select letter,count(*)from((select substr(name,2,1) letterfrom pub.student)union all(select substr(name,3,1) letterfrom pub.studentwhere substr(name,3,1) is not null))group by letter
)

 关键点:

1、第三个字有可能为空(有的人名字两个字),防止取出NULL,需要用where进行筛选

2、union all:保留所有的记录
      union:删除重复的记录

题目三(难题)

先创建“学院班级学分达标情况统计表1”test5_03,依据pub.student, pub.course,pub.student_course统计形成表中各项数据,成绩>=60为及格计入学分,总学分>=10算作达标,院系为空值的数据不统计在下表中,表结构:院系名称dname、班级class、学分达标人数p_count1、学分未达标人数p_count2、总人数p_count。

创建表格

create table test5_03
(dname varchar2(30),class varchar(10),p_count1 int,p_count2 int,p_count int
)

更新dname,class,以及总人数:

insert into test5_03(dname,class,p_count)(select dname,class,count(sid)from pub.studentwhere dname is not nullgroup by dname,class
)

更新学分达标人数p_count1 

update test5_03 tset p_count1=(select count(sid)from(select S.sid,S.dname,S.classfrom pub.student S,pub.course C,(SELECT sid, cid, MAX(score) AS max_scoreFROM pub.student_courseGROUP BY sid, cid) SCwhere S.sid = SC.sid and C.cid=SC.cid and SC.max_score >= 60group by S.sid,S.dname,S.classhaving sum(C.credit)>=10)awhere t.dname=a.dnameand t.class=a.class)

 更新学分未达标人数p_count2

update test5_03 tset p_count2=(select count(sid)from((select S.dname,S.class,S.sidfrom pub.student S,pub.course C,(SELECT sid, cid, MAX(score) AS max_scoreFROM pub.student_courseGROUP BY sid, cid) SCwhere SC.sid=S.sidand SC.cid=C.cidand SC.max_score>=60group by S.dname,S.class,S.sidhaving sum(C.credit)<10) union(select dname,class,sidfrom pub.studentwhere sid not in(select sidfrom pub.student_course)))awhere t.dname=a.dnameand t.class=a.class)

关键点:

1、统计学分达标人数和未达标人数的答题思路是相似的。可以将这个问题进行分解:

  •  统计人数,所以要select count(sid)
  •  统计达标的人数,所以from里面的表格一定都是已经达标的,也就是要筛选出达标的人
  •  达标也就是学分大于10,统计学分可以对选课表格按每个学院每个年级每个人进行分组,然后再统计sum(credit)
  • 要注意这个选课表格分组前也需要筛选出分数大于60的课

2、利用自然连接时,要注意大集合连接小集合会导致部分数据缺失。我们要考虑我们需要的from数据是大集合中的还是小集合中的,如上题:

  • 统计未达标人数时,因为前面的筛选、更新操作是在student_course自然连接student表格中进行的,所以如果有学生没有选课的话,就不会出现在筛选结果中。而学分未达标人数中需要包括这些没有选课的同学,所以在from中需要用union对集合进行合并增加

3、is只适用于null前面:is null;is not null.

     in和not in适用于select前面

4、用insert进行插入时,如果插入内容select的列数与表格数目不相同,那么一定要在插入时明确插入到哪些列

5、更新p_count1、2时where语句在set语句内,因为要保证一个数值位对应一个数值

6、考虑到有的学生存在同一门课程参与多次考试的情况,并且每一次考试都大于60,那么此时在筛选60分以上成绩后该学生仍然有多次成绩,直接sum(credit)会导致学分重复计算。这要求我们要对重复成绩进行删除,删除方法有:1、select distinct;2、利用sid、cid分组后选出max(score),并用这个结果作为新的from内的关系(from中可以用select结果作为新关系)

题目四 

创建“学院班级学分达标情况统计表2”test5_04,依据pub.student, pub.course,pub.student_course统计形成表中各项数据,成绩>=60为及格计入学分,2008级及之前的班级总学分>=8算作达标,2008级之后的班级学分>=10算作达标,院系为空值的数据不统计在下表中,表结构:院系名称dname、班级class、学分达标人数p_count1、学分未达标人数p_count2、总人数p_count。

创建表

create table test5_04 
(dname varchar2(30),class varchar(10),p_count1 int,p_count2 int,p_count int
)

关键点:

1、直接create后面不需要as,可以直接写创建的表的结构

2、create as后面接select操作来实现对表格结构表格源数据的复制

3、create like后面跟 table_name 可以复制表格结构

4、oracle中不能用like

 更新p_count1

update test5_04 t set p_count1 = 
(select count(sid)
from 
((select S.sid,S.dname,S.classfrom pub.student S,pub.course C,(SELECT sid, cid, MAX(score) AS max_scoreFROM pub.student_courseGROUP BY sid, cid) SCwhere S.sid = SC.sid and C.cid=SC.cid and SC.max_score >= 60 and S.class > 2008group by S.sid,S.dname,S.classhaving sum(C.credit) >= 10) union(select S.sid,S.dname,S.classfrom pub.student S,pub.course C,(SELECT sid, cid, MAX(score) AS max_scoreFROM pub.student_courseGROUP BY sid, cid) SCwhere S.sid = SC.sid and C.cid=SC.cid and SC.max_score >= 60 and S.class <= 2008group by S.sid,S.dname,S.classhaving sum(C.credit) >= 8)
) temp
where t.dname = temp.dname and t.class  = temp.class)

更新p_count2

update test5_04 t set p_count2 = 
(select count(sid)from ((select S.sid,S.dname,S.classfrom pub.student S,pub.course C,(SELECT sid, cid, MAX(score) AS max_scoreFROM pub.student_courseGROUP BY sid, cid) SCwhere S.sid = SC.sid and C.cid=SC.cid and SC.max_score >= 60 and S.class > 2008group by S.sid,S.dname,S.classhaving sum(C.credit) < 10) union (select S.sid,S.dname,S.classfrom pub.student S,pub.course C,(SELECT sid, cid, MAX(score) AS max_scoreFROM pub.student_courseGROUP BY sid, cid) SCwhere S.sid = SC.sid and C.cid=SC.cid and SC.max_score >= 60 and S.class <= 2008group by S.sid,S.dname,S.classhaving sum(C.credit) < 8) union(select sid,dname,class from pub.student where sid not in(select sid from pub.student_course))
) temp
where t.dname = temp.dname and t.class  = temp.class)

关键点:

1、本题思路和前一题是完全相同的,就是增加更新条件,重复更新几次 

题目五

查询各院系(不包括院系名称为空的)的数据结构平均成绩avg_ds_score、操作系统平均成绩avg_os_score,平均成绩四舍五入到个位,创建表test5_05

create view test5_05 as (
select *
from(select S.dname,round(avg(SC.max_score)) avg_ds_scorefrom pub.student S,pub.course C,(select sid,cid,max(score) max_scorefrom pub.student_coursegroup by sid,cid)SCwhere S.sid=SC.sid and C.cid=SC.cid and C.name='数据结构' and S.dname is not nullgroup by S.dname)natural full outer join(select S.dname,round(avg(SC.max_score)) avg_os_scorefrom pub.student S,pub.course C,(select sid,cid,max(score) max_scorefrom pub.student_coursegroup by sid,cid)SCwhere S.sid=SC.sid and C.cid=SC.cid and C.name='操作系统' and S.dname is not nullgroup by S.dname)
)

关键点:

1、实验要求创建视图而不是创建临时表 。很多时候在软件开发中我们都是创建一个视图对临时变量进行处理,因为这样不占用内存空间

2、对视图的处理一般只能是select,因为视图是基本表的复制品而不是表格本身。对视图进行insert和updata没有什么意义

3、两个select结果进行自然全外连接从而完成匹配

4、按照dname分组前需要筛选dname不为空

题目六

查询”计算机科学与技术学院”的同时选修了数据结构、操作系统两门课的学生的学号sid、姓名name、院系名称dname、数据结构成绩ds_score、操作系统成绩os_score,创建表test5_06

create view test5_06 as (
select *
from(select S.sid,S.name,S.dname,SC.max_score ds_scorefrom pub.student S,pub.course C,(select sid,cid,max(score) max_scorefrom pub.student_coursegroup by sid,cid)SCwhere S.sid=SC.sid and C.cid=SC.cid and S.dname='计算机科学与技术学院' and C.name='数据结构' and S.sid in((select sidfrom pub.student_course SC,pub.course Cwhere C.cid=SC.cid and C.name='数据结构')intersect(select sidfrom pub.student_course SC,pub.course Cwhere C.cid=SC.cid and C.name='操作系统')))natural full outer join(select S.sid,S.name,S.dname,SC.max_score os_scorefrom pub.student S,pub.course C,(select sid,cid,max(score) max_scorefrom pub.student_coursegroup by sid,cid)SCwhere S.sid=SC.sid and C.cid=SC.cid and S.dname='计算机科学与技术学院' and C.name='操作系统' and S.sid in((select sidfrom pub.student_course SC,pub.course Cwhere C.cid=SC.cid and C.name='数据结构')intersect(select sidfrom pub.student_course SC,pub.course Cwhere C.cid=SC.cid and C.name='操作系统')))
)

关键点:

1、select选数据结构、选操作系统的学生sid结果取交集成一个新关系。让参与平均分计算的学生sid在这个关系中

题目七 

查询计算机科学与技术学院的选修了数据结构或者操作系统的学生的学号sid、姓名name、院系名称dname、数据结构成绩ds_score、操作系统成绩os_score,创建表test5_07

create view test5_07 as (
select *
from(select S.sid,S.name,S.dname,SC.max_score ds_scorefrom pub.student S,pub.course C,(select sid,cid,max(score) max_scorefrom pub.student_coursegroup by sid,cid)SCwhere S.sid=SC.sid and C.cid=SC.cid and S.dname='计算机科学与技术学院' and C.name='数据结构' and S.sid in((select sidfrom pub.student_course SC,pub.course Cwhere C.cid=SC.cid and C.name='数据结构')union(select sidfrom pub.student_course SC,pub.course Cwhere C.cid=SC.cid and C.name='操作系统')))natural full outer join(select S.sid,S.name,S.dname,SC.max_score os_scorefrom pub.student S,pub.course C,(select sid,cid,max(score) max_scorefrom pub.student_coursegroup by sid,cid)SCwhere S.sid=SC.sid and C.cid=SC.cid and S.dname='计算机科学与技术学院' and C.name='操作系统' and S.sid in((select sidfrom pub.student_course SC,pub.course Cwhere C.cid=SC.cid and C.name='数据结构')union(select sidfrom pub.student_course SC,pub.course Cwhere C.cid=SC.cid and C.name='操作系统')))
)

关键点:

1、整体思路和上题完全相同,仅仅是将intersect改为union

2、集合交:intersect

     集合并: union

     集合差:minus

题目八

查询计算机科学与技术学院所有学生的学号sid、姓名name、院系名称dname、数据结构成绩ds_score、操作系统成绩os_score,创建表test5_08,表结构及格式如下

create view test5_08 as (
select *
from(select S.sid,S.name,S.dname,SC.max_score ds_scorefrom pub.student S,pub.course C,(select sid,cid,max(score) max_scorefrom pub.student_coursegroup by sid,cid)SCwhere S.sid=SC.sid and C.cid=SC.cid and S.dname='计算机科学与技术学院' and C.name='数据结构' )natural full outer join(select S.sid,S.name,S.dname,SC.max_score os_scorefrom pub.student S,pub.course C,(select sid,cid,max(score) max_scorefrom pub.student_coursegroup by sid,cid)SCwhere S.sid=SC.sid and C.cid=SC.cid and S.dname='计算机科学与技术学院' and C.name='操作系统')natural full outer join(select S.sid,S.name,S.dnamefrom pub.student Swhere S.dname = '计算机科学与技术学院' and S.sid not in (select S.sid from pub.student S,pub.course C,pub.student_course SC where S.sid = SC.sid and C.cid = SC.cid and (C.name = '数据结构' or C.name = '操作系统'))) 
)

关键点:

1、自然全外连接解决了只考了其中一门课学生的情况。但如果一个计算机科学与技术学院的学生没有考这两门课,那么他将不在自然全外连接的关系结果中。所以需要加上这一部分的学生

2、这里用来全新的思路来处理两门课中选一门的学生这个问题。在上一题中采用两个select取并集,本题中直接select语句中的where里面采用c.name用or连接(这个处理方式不能在同时选两门课中使用,同时选两门课仍然要用集合取并而不是and来处理!!)

题目九 

创建“成绩及格学生每个成绩人数百分比统计表” 视图test5_09,依据pub.student_course统计形成视图中各项数据,成绩>=60为及格,视图结构:成绩score、对应成绩人数count1、及格总人数count0、站总人数的百分比percentage(即前面两列相除后乘以100)。其中百分比四舍五入到小数点后面2位。输出按成绩排序。上面说的“人数”理解成 “人次”更加准确,亦既一个同学同一门考试考两次,算两人次。视图如下:

create view test5_09 as
with temp as(select SC.sid,SC.scorefrom pub.student_course SCwhere SC.score>=60
)
select temp.score,count(sid) count1,(select count(sid) from temp) count0,(round(count(sid)/(select count(sid) from temp),4)*100) percentage
from temp
group by score

关键点:

1、考虑到后面的查询都不能直接用pub.student_course进行,而是需要利用筛选后的这个表格。所以在select之前统一对pub.student_course进行筛选处理并创建新的临时表格

2、group by后的select有限制,只能是:a.group by的列 b.聚集函数 c.常数。

看这个select后面的对象,前两个score,count1自然对应a和b没有问题。

关键在于:count0和percentage为什么可以

3、count0:count0在这里是一个子查询,是对外表进行一个count统计,所以对于外部这个select来说,它眼中的count0就是一个确定的数,所以是常数。并且select会自动按照前面查询的行数去对这个常数进行复制填充

4、percentage:分为两个部分:前面是count(sid)对于select来说是一个聚集函数没有问题;后面是一个和3一样的子查询,结果是常数,对于外部select来说依旧没有问题,所以是符合语法要求的

5、在 percentage中前面是count(sid),所以对于每一个percentage行来说不用考虑和前面select对象行匹配的问题

题目十

创建“每个课程成绩在60-99分之间每段成绩的人数百分比统计表”视图test5_10,依据pub.course,pub.student_course统计形成视图中各项数据,仅仅统计成绩在60-99(包含60和99)之间成绩,视图结构:课程编号cid、课程名称cname、成绩score(这个列内容不要包含空格)、对应成绩人数count1、及格总人数count0(仅统计60-99分)、站总人数的百分比percentage(即前面两列相除后乘以100)。其中百分比四舍五入到小数点后面2位。输出按课程编号、成绩排序。上面说的“人数”理解成 “人次”更加准确,亦既一个同学同一门考试考两次,算两人次。

create or replace view test5_10 as
with temp as (select score, sid, cidfrom pub.student_coursewhere score >= 60 and score <= 149
)
selectsc.cid,c.name as cname,to_char(trunc(sc.score, -1), 'fm000') || '-' || to_char(trunc(sc.score, -1) + 9, 'fm000') as score,count(*) as count1,(select count(*)from tempwhere temp.cid = sc.cid) as count0,(round(count(sid)/(select count(*)from tempwhere temp.cid = sc.cid),4)*100) as percentage
frompub.course c,temp sc
wherec.cid = sc.cid
group bysc.cid,c.name,to_char(trunc(sc.score, -1), 'fm000') || '-' || to_char(trunc(sc.score, -1) + 9, 'fm000');

关键点:

1、 trunc(sc.score, -1):把score中的数向下处理为10的倍数(例如38——30,24——20)

2、to_char(......, 'fm000'):将前面.....的内容转为char类型并且改为3位数的输出(例如38——038)

3、select后面可以跟表达式,group by后面也可以跟表达式

下面是我一开始写的错误例子(改了好久。。。。。):

create or replace view test5_10 as
with temp as
(select score,sid,cid from pub.student_course where score>=60 and score<=149)select cid,C.name cname,to_char(trunc(score,-1),'fm000')||'-'||to_char(trunc(score,-1)+9,'fm000') Score,count(*)count1,(select count(*) from temp group by cid ) count0 //这行有问题
from pub.course C,temp SC
where C.cid=SC.cid
group by SC.cid,C.name,to_char(trunc(score,-1),'fm000')||'-'||to_char(trunc(score,-1)+9,'fm000') Score

这一行的问题在于cid聚集后count(*)得到的行数和外部select是不同的,此时sql就不知道要如何处理两者的匹配问题,就会报语法错误 

总结 

本文的所有题目均来自《数据库系统概念》(黑宝书)、山东大学数据库实验五。不可用于商业用途转发。

如果能帮助到大家,大家可以点点赞、收收藏呀~ 

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

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

相关文章

Docker容器:Docker-Consul 的容器服务更新与发现

目录 前言 一、什么是服务注册与发现 二、 Docker-Consul 概述 1、Consul 概念 2、Consul 提供的一些关键特性 3、Consul 的优缺点 4、传统模式与自动发现注册模式的区别 4.1 传统模式 4.2 自动发现注册模式 5、Consul 核心组件 5.1 Consul-Template组件 5.2 Consu…

esp32+mqtt协议+paltformio+vscode+微信小程序+温湿度检测

花费两天时间完成了这个项目&#xff08;不完全是&#xff0c;属于是在resnet模型训练和温湿度检测两头跑......模型跑不出来&#xff0c;又是第一次从头到尾独立玩硬件&#xff0c;属于是焦头烂额了......&#xff0c;完成这个项目后&#xff0c;我的第一反应是写个csdn&#…

如何delphi7中添加自定义的控件或组件

1.问题 为了编写方便&#xff0c;会自己生成一些自定义的控件。 XXX.PAS:源码文件&#xff0c;后续可以再调整 XXX.DCU:编译后的文件 2.解决办法 1.自定义控件的文件如下 2.将这些文件保留在程式代码中&#xff0c;万一丢失会导致程式开启后报是否忽略 3.选择菜单栏中的com…

简述前后端分离架构案例

Hello , 这里是小恒不会java 。今晚1点写写关于RESTful接口的使用案例&#xff0c;本文会通过django原生js前后端分离的案例简单讲解。本文带你认识一下简化版的前后端分离架构 代码 本文案例代码在GitHub上 https://github.com/lmliheng/fontend前后端分离 先说说什么是前后…

ue引擎游戏开发笔记(32)——为游戏添加新武器装备

1.需求分析&#xff1a; 游戏中角色不会只有一种武器&#xff0c;不同武器需要不同模型&#xff0c;甚至可能需要角色持握武器的不同位置&#xff0c;因此需要添加专门的武器类&#xff0c;方便武器后续更新&#xff0c;建立一个武器类。 2.操作实现&#xff1a; 1.在ue5中新建…

cmake进阶:文件操作

一. 简介 前面几篇文章学习了 cmake的文件操作&#xff0c;写文件&#xff0c;读文件。文章如下&#xff1a; cmake进阶&#xff1a;文件操作之写文件-CSDN博客 cmake进阶&#xff1a;文件操作之读文件-CSDN博客 本文继续学习文件操作。主要学习 文件重命名&#xff0c;删…

深入了解C/C++的内存区域划分

&#x1f525;个人主页&#xff1a;北辰水墨 &#x1f525;专栏&#xff1a;C学习仓 本节我们来讲解C/C的内存区域划分&#xff0c;文末会附加一道题目来检验成果&#xff08;有参考答案&#xff09; 一、大体有哪些区域&#xff1f;分别存放什么变量开辟的空间&#xff1f; …

深度神经网络中的不确定性研究综述

A.单一确定性方法 对于确定性神经网络&#xff0c;参数是确定的&#xff0c;每次向前传递的重复都会产生相同的结果。对于不确定性量化的单一确定性网络方法&#xff0c;我们总结了在确定性网络中基于单一正向传递计算预测y *的不确定性的所有方法。在文献中&#xff0c;可以找…

Fireworks AI和MongoDB:依托您的数据,借助优质模型,助力您开发高速AI应用

我们欣然宣布 MongoDB与 Fireworks AI 正携手合作 让客户能够利用生成式人工智能 (AI) 更快速、更高效、更安全地开展创新活动 Fireworks AI由 Meta旗下 PyTorch团队的行业资深人士于 2022 年底创立&#xff0c;他们在团队中主要负责优化性能、提升开发者体验以及大规模运…

【数据可视化-02】Seaborn图形实战宝典

Seaborn介绍 Seaborn是一个基于Python的数据可视化库&#xff0c;它建立在matplotlib的基础之上&#xff0c;为统计数据的可视化提供了高级接口。Seaborn通过简洁美观的默认样式和绘图类型&#xff0c;使数据可视化变得更加简单和直观。它特别适用于那些想要创建具有吸引力且信…

重写muduo之EPollPoller

1、EPollPoller.h EPollPoller的主要实现&#xff1a;作为poller的派生类&#xff0c;把基类给派生类保留的这些纯虚函数的接口实现出来。 override表示在派生类里面&#xff0c;这些方法是覆盖方法。必须由编译器来保证在基类里面一定有这些函数的接口的声明。在派生类要重写…

数据结构十一:数组相关经典面试题

本篇博客详细介绍分析数组/顺序表常见的面试题&#xff0c;对于前面所学知识进行一个巩固&#xff0c;同时介绍一些力扣刷题中的一些概念&#xff1a;如&#xff1a;输出型参数等&#xff0c;在刷题中培养自己的编程思维&#xff0c;掌握常见的编程套路&#xff0c;形成题感&am…