数据库:实验二

一、实验2.1 数据查询

1、要求

        以School数据库为例,在该数据库中存在四张表格,分别为:

  1. 表STUDENT(sid, sname, email, grade);
  2. 表TEACHERS(tid, tname, email, salary);
  3. 表COURSES(cid, cname, hour);
  4. 表CHOICES(no, sid, tid, cid, score)

        在数据库中,存在这样的关系:学生可以选择课程,一个课程对应一个教师。在表CHOICES中保存学生的选课记录。

2、按以下要求对数据库进行查询操作

(1)查询年级为2001的所有学生的名称并按编号升序排列。

SELECT sname FROM STUDENTS WHERE grade = '2001' ORDER BY sid;

(2)查询学生的选课成绩合格的课程成绩,并把成绩换算为积点(60分对应积点为1,每增加1分,积点增加0.1)。

SELECT sid, cid, (1 + (score - 60) * 0.1) AS points FROM CHOICES WHERE score >= 60;

 (3)查询课时是48或64的课程的名称。

SELECT cname FROM COURSES WHERE hour IN (48, 64);

 (4)查询所有课程名称中含有data的课程编号。

SELECT cid FROM COURSES WHERE cname LIKE '%data%';

(5)查询所有选课记录的课程号(不重复显示)。

SELECT DISTINCT cid FROM CHOICES;

(6)统计所有教师的平均工资。

SELECT AVG(salary) FROM TEACHERS;

(7)查询所有教师的编号及选修其课程的学生的平均成绩,按平均成绩降序排列。

SELECT tid, AVG(score) AS avg_score FROM CHOICES GROUP BY tid ORDER BY avg_score DESC;

(8)统计各个课程的选课人数和平均成绩。

SELECT cid, COUNT(sid) AS num_students, AVG(score) AS avg_score FROM CHOICES GROUP BY cid;

(9)查询至少选修了三门课程的学生编号。

SELECT sid FROM CHOICES GROUP BY sid HAVING COUNT(cid) >= 3;

(10)查询编号800009026的学生所选的全部课程的课程名和成绩。

SELECT COURSES.cname, CHOICES.score FROM CHOICES JOIN COURSES ON CHOICES.cid = COURSES.cid WHERE sid = '800009026';

 (11)查询所有选修了database的学生的编号。

SELECT CHOICES.sid FROM CHOICES JOIN COURSES ON CHOICES.cid = COURSES.cid WHERE COURSES.cname = 'database';

(12)求出选择了同一个课程的学生数。

SELECT cid, COUNT(sid) AS student_count FROM CHOICES GROUP BY cid;

(13)求出至少被两名学生选修的课程编号。

SELECT cid FROM CHOICES GROUP BY cid HAVING COUNT(sid) >= 2;

(14)查询选修了编号800009026的学生所选的某个课程的学生编号。

SELECT sid FROM CHOICES WHERE cid IN (SELECT cid FROM CHOICES WHERE sid = '800009026');

(15)查询学生的基本信息及选修课程编号和成绩。

SELECT STUDENTS.*, CHOICES.cid, CHOICES.score FROM STUDENTS JOIN CHOICES ON STUDENTS.sid = CHOICES.sid;

(16)查询学号850955252的学生的姓名和选修的课程名及成绩。

SELECT STUDENTS.sname, COURSES.cname, CHOICES.score FROM STUDENTS JOIN CHOICES ON STUDENTS.sid = CHOICES.sid JOIN COURSES ON CHOICES.cid = COURSES.cid WHERE STUDENTS.sid = '850955252';

850955252同学的信息没找到,用800009026同学验证 

(17)查询与学号850955252的学生同年级的所有学生资料。

SELECT * FROM STUDENTS WHERE grade IN (SELECT grade FROM STUDENTS WHERE sid = '850955252');

(18)查询所有有选课的学生的详细信息。

SELECT DISTINCT STUDENTS.* FROM STUDENTS JOIN CHOICES ON STUDENTS.sid = CHOICES.sid;

(19)查询没有学生选的课程的编号。

SELECT cid FROM COURSES WHERE cid NOT IN (SELECT cid FROM CHOICES);

(20)查询与课程名为c++的课时一样的课程名称。

SELECT cname FROM COURSES WHERE hour = (SELECT hour FROM COURSES WHERE cname = 'c++');

(21)找出选修课程成绩最好的选课记录。

SELECT * FROM CHOICES WHERE score = (SELECT MAX(score) FROM CHOICES);

(22)找出和课程c或课程c++的课时一样课程名称。

SELECT cname FROM COURSES WHERE hour IN (SELECT hour FROM COURSES WHERE cname = 'c' OR cname = 'c++');

(23)查询所有选修编号10001的课程的学生的姓名。

SELECT sname FROM STUDENTS JOIN CHOICES ON STUDENTS.sid = CHOICES.sid WHERE cid = '10001';

(24)查询选修了所有课程的学生姓名。

SELECT sname FROM STUDENTS WHERE sid NOT IN (SELECT sid FROM STUDENTS EXCEPT SELECT sid FROM CHOICES);

(25)利用集合运算,查询选修课程c++或选修课程c的学生的编号。

SELECT sid FROM CHOICES WHERE cid IN (SELECT cid FROM COURSES WHERE cname = 'c++' UNION SELECT cid FROM COURSES WHERE cname = 'c');

(26)实现集合交运算,查询既选修课程c++又选修课程c的学生的编号。

SELECT sid FROM CHOICES WHERE cid IN (SELECT cid FROM COURSES WHERE cname = 'c++') INTERSECT SELECT sid FROM CHOICES WHERE cid IN (SELECT cid FROM COURSES WHERE cname = 'c');

(27)实现集合减运算,查询选修课程c++而没有选修课程c的学生的编号。

SELECT sid FROM CHOICES WHERE cid IN (SELECT cid FROM COURSES WHERE cname = 'c++') EXCEPT  SELECT sid FROM CHOICES WHERE cid IN (SELECT cid FROM COURSES WHERE cname = 'c');

二、实验2.2 空值和空集的处理

1、按以下要求对数据库进行查询操作

(1)查询所有选课记录的成绩并将它换算为五分制(满分5分,合格3分),注意SCORE取NULL值的情况。

SELECT     no, sid, tid, cid, score*0.05

FROM         CHOICES

where      score is not null

(2)通过查询选修编号10028的课程的学生的人数,其中成绩合格的学生人数,不合格的学生人数,讨论NULL值的特殊含义。

        count 对null记录取为0,score<60比较中,如果是null,结果为unknown,而只有当结果是true时才被选入结果

SELECT     COUNT(sid) AS Expr1

FROM         CHOICES

WHERE     (cid = '10028')

SELECT     COUNT(sid) AS Expr2

FROM         CHOICES

WHERE     (cid = '10028' and score>=60)

SELECT     COUNT(sid) AS Expr3

FROM         CHOICES

WHERE     (cid = '10028' and score<60)

(3)通过实验检验在使用ORDER BY进行排序时,取NULL的项是否出现在结果中?如果有,在什么位置?

有出现,被认为最小

SELECT     CHOICES.*

FROM         CHOICES

WHERE     (cid = '10028')

ORDER BY score desc

(4)在上面的查询过程中如果加上保留字DISTINCT会有什么效果?

SELECT     distinct   score, cid  

FROM         CHOICES

WHERE     (cid = '10028')

ORDER BY score desc

删去DISTINCT后会出现重复的结果  

(5)通过实验说明使用分组GROUP BY对取值为NULL的项的处理。

SELECT     COUNT(sid) AS Expr1, score

FROM         CHOICES

GROUP BY score

SELECT     COUNT(sid) AS Expr2

FROM         CHOICES

where    score is null

NULL会被单独分为一类

(6)结合分组,使用集合函数求每个同学的平均分、总的选课记录、最高成绩、最低成绩和总成绩。

SELECT     sid ,COUNT(cid) AS 总选课数, AVG(score) AS 平均分, MAX(score) AS 最高成绩, MIN(score) AS 最低成绩

FROM         CHOICES

GROUP BY sid

(7)查询成绩小于60的选课记录,统计总数、平均分、最大值和最小值。

SELECT     sid, score

FROM         CHOICES

WHERE     (score < 60)

SELECT     COUNT('CHOICES.*') AS 总记录, AVG(score) AS 平均分, MAX(score) AS 最高分, MIN(score) AS 最低分

FROM         CHOICES

WHERE     (score < 60)

(8)采用嵌套查询的方式,利用比较运算符和谓词ALL的结合来查询表COURSES中最少的课时。假设数据库中只有一个记录的时候,使用前面的方法会得到什么结果,为什么?

SELECT * from COURSES

WHERE hour<=all(select hour from COURSES)

SELECT MIN(hour) FROM COURSES

CREATE TABLE oneCOURSES(

cid CHAR(18) NOT NULL,

cname CHAR(20),

hour int

);

INSERT INTO oneCOURSES VALUES(

'12138',

'cs',

48

);

select * from oneCOURSES

WHERE hour<=all(select hour from oneCOURSES)

SELECT MIN(hour) FROM oneCOURSES

当只有一条记录时,这条记录的课时会是最少的,因为它同时是最大和最小的课时。

(9)创建一个学生表S(NO, SID, SNAME),教师表T(NO, TID, TNAME)作为实验用的表。其中NO分别是这两个表的主键,其他键允许为空。

create table S

(NO CHAR(9) PRIMARY KEY,

 SID CHAR(20),

 SNAME CHAR(20)

);

create table T

(NO CHAR(9) PRIMARY KEY,

 TID CHAR(20),

 TNAME CHAR(20)

);

(10)向S插入元组(1, 0129871001, 王小明)、(2, 0129871002, 李兰)、(3, 0129871005, NULL)、(4, 0129871004, 关红);

insert into S(NO,SID,SNAME) values('1','0129871001','王小明');

insert into S values('2','0129871002','李兰');

insert into S(NO,SID,SNAME) values('3','0129871005',null);

insert into S(NO,SID,SNAME) values('4','0129871004','关红');

(11)向T插入元组1, 100189, 王小明)、(2, 100180, 李小)、(3, 100121, NULL)、(4, 100128, NULL)。

insert into T values('1','100189','王小明');

insert into T values('2','100180','李小');

insert into T values('3','100121',null);

insert into T values('4','100128',null);

(12)对这两个表作对姓名的等值连接运算,找出既是老师又是学生的人员的学生编号和老师编号。

select S.NO,T.NO from S JOIN T ON S.SNAME=T.TNAME;

NULL值在比较中不会判等,所以不会出现(3,3)(3,4)这样的记录 

  • 19
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值