数据库作业五

例题练习

我们操作例题默认使用下表

Create Table student(
Sno char(12) Primary Key, 
Sname char(12),
Ssex char(2),
Sdept char(40),
Sage SmallInt
);
Insert Into Student Values ('20191102062','刘哲轩','男','Computer Science',19)
Insert Into Student Values ('20191102063','叶晓晓','男','information security',20)
Insert Into Student Values ('20191102064','刘小轩','女','Computer Science',21)
Insert Into Student Values ('20191102065','叶大大','男','information security',20)
Insert Into Student Values ('20191102066','刘大轩','男','Computer Science',22)
Insert Into Student Values ('20191102067','刘轩','女','information security',20)
Insert Into Student Values ('20191102068','刘车干','男','Computer Science',19)
Insert Into Student Values ('20191102069','刘刘','女','information security',20)
Insert Into Student Values ('20191102070','刘刘流','男','Computer Science',22)
Insert Into Student Values ('20191102071','叶小刘','女','information security',20)
Create Table Course(
   Cno Char(12) Primary Key,--课序号
   Cname Char(12),
   Cpno Char(12),--先行课的课序号
   Ccredit SmallInt,
   Foreign Key(Cpno) References Course(Cno)
);
Insert Into Course Values('1','数据库',null,4)
Insert Into Course Values('2','数学',null,2)
Insert Into Course Values('3','信息系统',null,4)
Insert Into Course Values('4','操作系统',null,3)
Insert Into Course Values('5','数据结构',null,4)
Insert Into Course Values('6','数据处理',null,2)
Insert Into Course Values('7','PASCAL语言',null,4)
update course set cpno='5' where cno='1'
update course set cpno='1' where cno='3'
update course set cpno='6' where cno='4'
update course set cpno='7' where cno='5'
update course set cpno='6'where cno='7'
Create Table SC(--学生选课表
  Sno Char(12),
  Cno Char(12),
  Grade SmallInt,
  Primary Key(Sno, Cno),
  Foreign Key(Sno) References Student(Sno),
  Foreign Key(Cno) References Course(Cno)
);
Insert Into SC Values('20191102062', '1', 100)
Insert Into SC Values('20191102062', '2', 51)
Insert Into SC Values('20191102063', '1', 65)
Insert Into SC Values('20191102064', '2', 46)
Insert Into SC Values('20191102065', '3', 85)
Insert Into SC Values('20191102066', '3', 95)
Insert Into SC Values('20191102067', '7', 99)
Insert Into SC Values('20191102068', '6', 93)

例3.19 查询全体学生的姓名及其出生年份

SELECT子句的<目标列表达式>不仅可以是表中的属性列,也可以是表达式。
代码如下:

Select Sname, 2020 - Sage from student

查询结果中第2列不是列名而是一个计算表达式,是用当时的年份(假设为2020年)减去学生的年龄。这样所得的即是学生的出生年份。输出的结果为


该操作会使sql临时产生一个新的无名字的列,值为 2020 − S a g e 2020 - Sage 2020Sage。如果想要给新的列命名为出生日期,可使用以下代码:

Select Sname, 2020 - Sage as '出生日期' from student

结果如下:

在这里插入图片描述

例3.20 查询全体学生姓名、出生日期和所在院系,要求使用小写字母表示系名

Select Sname, 'Year of Birth: ' as 'Year of Birth', 2020 - Sage, Lower(Sdept) From Student;

结果如下:
在这里插入图片描述
用户可以通过指定别名来改变查询结果的列标题,这对于含算术表达式、常量、函数名的目标列表达式尤为有用。例如对于例3.20可以定义如下列别名:

Select Sname, 'Year of Birth: '  Birth, 2020 - Sage Birthday, Lower(Sdept) From Student Department;

结果如下:
在这里插入图片描述

例3.21 查询选修了课程的学生学号

两个本来并不完全相同的元组在投影到指定的某些列上后,可能会变成相同的行。可以用 DISTINCT 消除它们。

Select Sno   From SC;
--等价于:
Select All  Sno  From SC;

效果如下:
在这里插入图片描述
如想去掉重复行,可使用以下代码

Select Distinct  Sno  From SC;

例3.22 查询计算机科学系全体学生的名单

查询满足指定条件的元组可以通过 WHERE子句实现。WHERE子句常用的查询条件
如下
在这里插入图片描述

Select Sname From  Student
Where  Sdept='Computer Science'; 

关系数据库会检查Sdept是否会等于’Computer Science’, 然后会找出所有满足条件的行,以Sname作为结果输出
结果如下:
在这里插入图片描述

例3.23 查询所有年龄在20岁一下的学生姓名及年龄

Select Sname, Sage From Student Where Sage < 20

在这里插入图片描述

例3.24 查询考试不及格的学生的学号

Select Distinct Sno From SC Where Grade < 60

distinct可以去重, 为了体现这一点, 我们在SC表中加入一行

Insert Into SC Values('20191102062', '3', 51)

结果如下:
在这里插入图片描述
当选择两列时,去重效果如下:

Select Distinct Sno, Cno From SC Where Grade < 60

这说明了选择两列及以上之后,只有每一列都相等的才算相等, 才会被去重,与主码无关
在这里插入图片描述

例3.25 查询年龄在20~23岁之间的学生姓名、系别和年龄

Between…And语句可以找出特定范围内的元组,between后的是下界,and后的是上界

Select Sname, Sdept, Sage From Student Where Sage Between 20 And 23

结果如下:
在这里插入图片描述
Between ... And语句是两端的闭区间, 当要选择开区间时,可以根据容斥原理, 配合Not选出所需的开区间.

例3.26 查询年龄不在20~23岁之间的学生姓名、系别和年龄

Select Sname, Sdept, Sage From Student Where Sage Not Between 20 And 23

结果如下:
在这里插入图片描述

例3.27 查询计算机科学系(Computer Science)和信息系(Information Science)学生的姓名和性别.

谓词In可以用来查找属于特定集合的元组

Select Sname, Ssex From Student Where Sdept In ('Computer Science', 'Information Security');

结果如下:
在这里插入图片描述

例3.28 查询既不是计算机科学系(Computer Science)也不是信息系(Information Science)学生的姓名和性别.

与In相对的谓词是Not In,用于查找属性值不属于指定集合的元组

Select Sname, Ssex From Student Where Sdept Not In ('Computer Science');

结果如下:

例3.29 查询学号为20191102062的学生的详细情况

当无法确切知道所要查找的值,而是知道所要查找的数据符合的模式时,可以使用LIKE 子句进行匹配。
谓词LIKE可以用来进行字符串的匹配。其一般语法格式如下;

[NOT] LIKE'<匹配串>' [ESCAPE '<换码字符>']

其含义是查找指定的属性列值与<匹配串>相匹配的元组。<匹配串>可以是一个完整的字符串,也可以含有通配符%和_其中:
%(百分号)代表任意长度(长度可以为0)的字符串。例如a%b表示以a开头,以b结尾的任意长度的字符串。如 acb、addgb、ab等都满足该匹配串。
·_(下横线)代表任意单个字符。
例如a b表示以a开头,以b结尾的长度为3的任意字符串。如 acb、afb等都满足该匹配串。

Select *  From  Student Where  Sno Like '20191102062';

结果如下:
在这里插入图片描述
如果将Like 换成 =号, 会出现下面这种结果: 在这里插入图片描述
跟like的一模一样, 这说明在没有通配符的情况下, like和=号的效果一致.
如果 LIKE 后面的匹配串中不含通配符,则可以用=(等于)运算符取代 LIKE谓词,用!=或(不等于)运算符取代NOT LIKE谓词。

例3.30 查询所有姓刘的学生的姓名、学号和性别

Select Sname, Sno, Ssex  From Student Where  Sname Like '刘%';

这查询选出来所有的刘姓成员.此时如果将Like改为=号,查询为空。
在这里插入图片描述

例3.31 查询所有姓刘且全名不超过三个汉字的学生的姓名

Selcet Sname, Sno, Ssex From Student Where Sname Like '刘__'

结果如下:
在这里插入图片描述
假如我们把’刘__‘改为’刘_’, 会发现只输出了名为’刘轩’和‘刘刘’的男子, 这说明了_这个通配符代表了最多的匹配字符数量,可以比_的数量少, 但是不可以多.

例3.32 查询名字中第二个字为‘晓’的学生的姓名和学号

为了进行对比, 我们在原表中加入一个新行

注意:数据库字符集为ASCII时一个汉字需要两个;当字符集为GBK时只需要一个

Insert Into Student Values ('20191102072','叶晓大','男','information security',20)
Select Sname, Sno From Student Where Sname Like '_晓%'

结果如下:
在这里插入图片描述

例3.33 查询所有不姓刘的学生的姓名、学号和性别

Select Sname, Sno, Ssex  From Student Where  Sname Not Like '刘%';

在这里插入图片描述

例3.34 查询数据_库课程的课程号和学分

原表中没有以_为内容的课程名, 我们在Course表中额外加一行.

Insert Into Course Values('8','数据_库',null,4)
Select Cno,Ccredit From Course Where  Cname Like '数据\_库' Escape '\' ;

如果用户要查询的字符串本身含有通配符,此时就要使用Escape’<换码字符>‘短语对通配符进行转义了,Escape’‘表示’‘为换码字符,这样匹配串中紧跟在‘\’后面的字符’_'不再是通配符,而是普通字符了,有点类似于c语言中的'\\'语句
结果如下:
在这里插入图片描述

例3.35 查询以’数据_'开头,且倒数第三个字符是1的课程的详细情况

老规矩, 在Course的表中再加一行’数据_库1111’

Insert Into Course Values('9','数据_库1111',null,4)
Select Cno,Ccredit From Course Where  Cname Like '数据\_%1__' Escape '\' ;

结果如下:
在这里插入图片描述

例3.36 某些学生选修课程后没有参加考试,所以有选课记录,但没有考试成绩,查询缺少成绩的学生的学号和相应的课程号

Insert Into SC Values('20191102071', '7', Null)
Insert Into SC Values('20191102069', '7', Null)
Select Sno,Cno From SC WHERE  Grade Is Null

结果如下:
在这里插入图片描述
Is不能改为=, 改成等于后, 查询为空.

例3.37 查所有有成绩的学生学号和课程号

Select Sno,Cno From SC WHERE  Grade Is Not Null

结果如下:
在这里插入图片描述

例3.38 查询计算机科学系年龄在20岁一下的学生姓名

逻辑运算符AND 和OR可用来连接多个查询条件。AND的优先级高于OR,
但用户可以用括号改变优先级。

Select Sname From Student Where Sdept = 'Computer Science' And Sage < 20

结果如下:
在这里插入图片描述
例3.27的改写:
In谓词实际上是多个Or运算符的缩写

---Select Sname, Ssex From Student Where Sdept In ('Computer Science', 'Information Security');
Select Sname, Ssex From Student Where Sdept = 'Computer Science' Or 'Information Security'

结果如下, 与例3.27相同
在这里插入图片描述

例3.39 查询选修了3号课程的学生的学号及其成绩, 查询结果按降序排列

用户可以用ORDER BY子句对查询结果按照一个或多个属性列的升序(ASC)或降序(DESC)排列,默认值为升序。
对于空值,排序时显示的次序由具体系统实现来决定。例如按升序排,按空值的元组最后显示;按降序排,空值的元组最先显示。各个系统的实现可以不同,只要保持一致即可

Select Sno, Grade From Sc Where Cno = '3' Order By Grade Desc;
Select Sno, Grade From Sc Where Cno = '3' Order By Grade Asc;
Select Sno, Grade From Sc Where Cno = '3' Order By Grade;

结果如图:
在这里插入图片描述
Order可以对表进行排序, Desc是降序排序, 以Grade为关键字, Asc是升序,下面分别是降序排序, 升序排序和默认排序的结果, 可以看出, 默认排序是升序排序.

例3.40 查询全体学生情况, 查询结果按所在系的系号升序排列,同一系中的学生按年龄降序排列

Select * From Student Order By Sdept, Sage Desc;

结果如下:
在这里插入图片描述这说明了当order后面有多个关键字时, 先按第一关键字排序, 再按第二关键字排序…以此类推。
再次选择学生表, 发现学生表的顺序并未发生变化,这说明了order只是创建一个临时排序表, 类似与python中的sorted函数

例3.41查询学生总人数

Count是一个聚集函数,可以计算出表的元组个数或者列的个数
当聚集函数遇到空值时,除 COUNT()外,都跳过空值而只处理非空值。COUNT ()是对元组进行计数,某个元组的一个或部分列取空值不影响COUNT的统计结果

Select Count(*) as '学生数' From Student

结果如下:
在这里插入图片描述

例3.42查询了选修课程的学生总人数

下列代码将SC表按照Sno为关键字去重后输出Sno列的行数

Select Count(Distinct Sno) From Sc;

结果如下:
在这里插入图片描述

例3.43计算选修了1号课程学生的平均成绩

Avg函数的作用是求出某一列的平均值,该列必须是数值型

Select Avg(Grade) From SC Where Cno = '1'

结果如下:
在这里插入图片描述

对字符型使用avg函数会报错:
在这里插入图片描述

例3.44查询选修1号课程的学生最高分数

Max函数的作用是求出某一列的平均值,该列必须是数值型

Select Max(Grade) From SC Where Cno = '1'

结果如下:
在这里插入图片描述

例3.45查询学生20191102062选修课程的总学分数

Sum函数的作用是求出某一列的和,该列必须是数值型

Select Sum(Ccredit) From SC, Course Where Sno = '20191102062' And Sc.Cno = Course.Cno; 

结果如下:
在这里插入图片描述

例3.46求各个课程号及相应的选课人数

GROUP BY子句将查询结果按某一列或多列的值分组,值相等的为一组。
对查询结果分组的目的是为了细化聚集函数的作用对象。如果未对查询结果分组,聚集函数将作用于整个查询结果,如前面的例3.41~3.45。分组后聚集函数将作用于每一个组,即每一组都有一个函数值。
该语句对查询结果按Cno的值进行分组, 所有具有相同Cno的值的元组为一组,然后对每一组作用的聚集函数Count进行计算,求出该组的学生人数.

Select Cno, Count(Sno) From SC Group By Cno;

在这里插入图片描述

例3.47查询选修了三门以上课程的学生学号

如果分组后还要求按一定的条件对这些组进行筛选,最终只输出满足指定条件的组,则可以使用HAVING短语指定筛选条件。
这里先用GROUP BY子句按Sno进行分组,再用聚集函数COUNT 对每一组计数;HAVING 短语给出了选择组的条件,只有满足条件(即元组个数>3,表示此学生选修的课超过3门)的组才会被选出来。WHERE 子句与 HAVING短语的区别在于作用对象不同。WHERE 子句作用于基本表或视图,从中选择满足条件的元组。HAVING短语作用于组,从中选择满足条件的组。

Select Sno From SC Group By Sno Having Count(*) > 3 

在这里插入图片描述

例3.48查询平均成绩不低于90分的学生学号和平均成绩

下面语句是不对的

Select Sno, Avg(Grade) From SC Where Avg(Grade) >= 90 Group By Sno;

因为Where子句中是不能用聚集函数作为条件表达式的,正确的语句应该是

Select Sno, Avg(Grade) From SC Group By Sno Having Avg(Grade) >= 90;

结果如下:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_45834992/article/details/115415503