数据库系统原理--实验二 数据库定义与操作语言--习题答案

前言:历时几天,总算把这个实验做出来了。此文章实验的题目、答案、解析3部分组成,包含实现这个实验的所有代码和问题的解析教程等。读者可以直接复制代码到软件上运行操作。
说明:实验用的软件:SQL Server 2014版。
这篇文章内容有点多,会持续更新到完整…

一、题目

导入ScoreDB数据库,按照“实验2数据”,修改四张表内各个字段的类型以及宽度。完成后,实现以下操作:
数据库系统原理--实验二 数据库定义与操作语言--习题答案_第1张图片
数据库系统原理--实验二 数据库定义与操作语言--习题答案_第2张图片
数据库系统原理--实验二 数据库定义与操作语言--习题答案_第3张图片
数据库系统原理--实验二 数据库定义与操作语言--习题答案_第4张图片

2.1数据查询

  1. 查询选修了“数据结构”课程的同学姓名。
  2. 查询选修了课程号为’001’或’002’课程的学生学号、课程号和分数。
  3. 查询学过课程号为’001’但是没有学过课程号为’002’的课程的学生学号、课程号和分数。
  4. 查询至少有一门课与学号为’0700001’的学生所学相同的学生的学号和姓名。
  5. 查询至少选修了学号为“0700001”学生所选修的所有课程的学生姓名。
  6. 查询本月过生日的学生信息。
  7. 查询没有成绩的学生信息。(使用IN语句)
  8. 查询(没有)选修过课程的学生姓名。(使用IN语句)
  9. 查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩。
  10. 查找选修过课程名中包含“系统”的课程的同学学号、姓名和所在班级。
  11. 查找同时选修过“高等数学”和“离散数学”两门课程的同学学号、姓名以及该同学所选修的所有课程的课程名和相应成绩,按学号(升序)、成绩(降序)排序输出。
  12. 查询所有学生的选修信息,显示信息包括学号,选修门数,平均分和总分。
  13. 查询先修课是“计算机基础”的课程。(分别用自连接和IN语句实现)
  14. 查询至少有一门课程成绩超过85分的所有学生的信息,显示信息包括学号、课程号和分数。
  15. 查询至少有两门课程成绩超过85分的所有学生的学号。
  16. 查询平均成绩超过80分且选修3门及以上的所有学生的信息,显示信息包括学号、课程数目和分数。
  17. 查询所选修课程的成绩大于所有“002”号课程成绩的同学学号及相应课程的课程号和成绩。
  18. 查询选修了所有课程的学生姓名。

2.2数据操纵

  1. 将所有选修001课程的同学的成绩增加5分。
  2. 将李小勇同学选修课程的成绩增加30%。
  3. 将每个班级的学生人数填入到班级表的ClassNum列中。
  4. 在Student表中添加一条学生记录(学号:0800016,姓名:张三,籍贯:福建)。
  5. 求出每门课程的选修人数,把结果存放在新表CountC中。(用SELECT INTO语句实现)
  6. 求出每个学生的选修门数和平均分,把结果存放在新表CountSC中。(用INSERT SELECT语句实现)
  7. 删除刘方晨同学所有的选修记录。
  8. 删除选修了“操作系统”课程的选课记录。

2.3视图

  1. 创建视图vw1,该视图包含福建省的女学生信息。
  2. 创建视图vw2,该视图包含学生的学号、姓名、所选修的课程的课程号、课程名和成绩。
  3. 创建视图vw3,该视图每门课程的课程号、课程名、选修人数和平均分。
  4. 建立一个新的视图vw4,该视图包含学生姓名和年龄字段。将vw4中的年龄增加1岁。观察其运行结果并分析原因。
  5. 删除视图vw1中学号为 ‘0800007’ 的数据。

二、答案

创建表

//创建数据库ScoreDB
CREATE DATABASE ScoreDB
//使用数据库ScoreDB
USE ScoreDB
//创建Class表
CREATE TABLE Class(
classNo CHAR(6) NOT NULL,
className VARCHAR(30) NOT NULL,
institute VARCHAR(30),
grade SMALLINT,
classNum TINYINT
)
SELECT * FROM Class
//创建Course表
CREATE TABLE Course(
courseNo CHAR(3) NOT NULL,
courseName VARCHAR(30) NOT NULL,
creditHour numeric(1,0),
courseHour int,
priorCourse CHAR(3)
)
SELECT * FROM Course

CREATE TABLE Student(
studentNo CHAR(7) NOT NULL,
studentName VARCHAR(20) NOT NULL,
sex CHAR(2),
birthday SMALLDATETIME,
native VARCHAR(20),
nation VARCHAR(30),
classNo CHAR(6)
)
SELECT * FROM Student
DROP TABLE Student

CREATE TABLE Score(
studentNo CHAR(7) NOT NULL,
courseNo CHAR(3) NOT NULL,
score NUMERIC(3,0)
)
SELECT * FROM Score

DELETE FROM Course

INSERT INTO Class
VALUES
('CP0801','注册会计08_01班','会计学院',2008,NULL),
('CP0802','注册会计08_02班','会计学院',2008,NULL),
('CP0803','注册会计08_03班','会计学院',2008,NULL),
('CS0701','计算机科学与技术07_01班','信息管理学院',2007,NULL),
('CS0702','计算机科学与技术07_02班','信息管理学院',2007,NULL),
('CS0801','计算机科学与技术08_01班','信息管理学院',2008,NULL),
('ER0701','金融管理07_01班','金融学院',2007,NULL),
('IS0701','信息管理与信息系统07_01班','信息管理学院',2007,NULL),
('IS0801','信息信息管理与信息系统08_01班','信息管理学院',2008,NULL)

INSERT INTO Course
VALUES
('001','高等数学','6',96,NULL),
('002','离散数学','6',96,'001'),
('003','计算机基础','4',64,NULL),
('004','C语言程序设计','6',96,'003'),
('005','数据结构','4',64,'004'),
('006','数据库系统原理','5',80,'005'),
('007','操作系统','5',80,'003')

DELETE FROM Student
INSERT INTO Student
VALUES
('0700001','李小勇','男','1990/12/21 0:00:00','南昌','汉族','CS0701'),
('0700002','刘方晨','女','1990/11/11 0:00:00','九江','汉族','IS0701'),
('0700003','王红敏','女','1990/10/1 0:00:00','上海','汉族','IS0701'),
('0700004','张可立','男','1991/5/20 0:00:00','南昌','蒙古族','CS0701'),
('0700005','王红','男','1992/3/26 0:00:00','南昌','汉族','CS0702'),
('0800001','李勇','男','1990/12/21 0:00:00','南昌','蒙古族','CS0801'),
('0800002','刘晨','女','1990/11/11 0:00:00','九江','汉族','IS0801'),
('0800003','王敏','女','1990/10/1 0:00:00','上海','汉族','IS0801'),
('0800004','张立','男','1991/5/20 0:00:00','南昌','蒙古族','CS0801'),
('0800005','王红','男','1992/3/26 0:00:00','北京','汉族','CP0802'),
('0800006','李志强','男','1991/12/21 0:00:00','南昌','蒙古族','CP0802'),
('0800007','李立','女','1991/8/21 0:00:00','福建','畲族','IS0801'),
('0800008','黄小红','女','1991/8/9 0:00:00','云南','傣族','CS0801'),
('0800009','黄勇','男','1991/11/21 0:00:00','九江','汉族','CP0802'),
('0800010','李宏冰','女','1992/3/9 0:00:00','上海','汉族','CP0802'),
('0800011','江宏吕','男','1990/12/20 0:00:00','上海','汉族','CP0802'),
('0800012','王立红','男','1990/11/18 0:00:00','北京','汉族','CS0801'),
('0800013','刘小华','女','1991/7/16 0:00:00','云南','哈尼族','IS0801'),
('0800014','刘宏昊','男','1991/9/16 0:00:00','福建','汉族','IS0801'),
('0800015','吴敏','女','1992/1/20 0:00:00','福建','畲族','CP0802')


INSERT INTO score
VALUES
('0700001','001','98'),
('0700001','002','82'),
('0700001','006','56'),
('0700002','003','69'),
('0700002','004','87'),
('0700002','005','77'),
('0700002','007','90'),
('0700003','001','46'),
('0700003','002','38'),
('0700003','007','50'),
('0800001','001','70'),
('0800001','002','68'),
('0800001','003','70'),
('0800001','004','58'),
('0800001','005','88'),
('0800001','006','72'),
('0800001','007','71'),
('0800002','001','98'),
('0800002','002','60'),
('0800002','007','46'),
('0800003','001','70'),
('0800003','002','60'),
('0800003','007','50'),
('0800004','001','70'),
('0800004','003','98'),
('0800004','006','89'),
('0800004','007','80'),
('0800005','001','82'),
('0800005','002','80'),
('0800005','004','47'),
('0800005','005','90'),
('0800005','007','82'),
('0800006','001','78'),
('0800006','002','60'),
('0800006','003','69'),
('0800006','004','87'),
('0800006','005','77'),
('0800006','006',0),
('0800006','007','90'),
('0800007','002',0)

2.1数据查询

1. 查询选修了“数据结构”课程的同学姓名。
SELECT studentName
FROM Student,Course,Score
WHERE courseName='数据结构'
AND Student.studentNo=Score.studentNo
AND Course.courseNo=Score.courseNo

2. 查询选修了课程号为’001’或’002’课程的学生学号、课程号和分数。
//第一种
SELECT studentNo,courseNo,score
FROM Score
WHERE courseNo='001'
OR courseNo='002'
//第二种
SELECT studentNo,courseNo,score
FROM Score
WHERE courseNo IN (001,002)
3. 查询学过课程号为’001’但是没有学过课程号为’002’的课程的学生学号、课程号和分数。
SELECT studentNo,courseNo,score
FROM Score
WHERE courseNo='001'
AND studentNo NOT IN (
					SELECT studentNo
					FROM Score
					WHERE courseNo='002')

4.查询至少有一门课与学号为’0700001’的学生所学相同的学生的学号和姓名。
SELECT studentNo,studentName
FROM Student
WHERE studentNo IN(
				SELECT DISTINCT Score.studentNo
				FROM Score
				WHERE courseNo IN(
								SELECT courseNo
								FROM Score
								WHERE studentNo='0700001'))

5.查询至少选修了学号为“0700001”学生所选修的所有课程的学生姓名。
SELECT studentName--把学号对应的姓名查出来
FROM Student
WHERE studentNo IN(--至少选修了学号为“0700001”学生所选修的所有课程的学号查出来
					SELECT studentNo
					FROM Score
					WHERE CourseNo IN(--把学号为“0700001”学生所选修的所有课程查出来
										SELECT courseNo
										FROM Score
										WHERE studentNo='0700001')
					GROUP BY studentNo
					HAVING COUNT(studentNo)>=3)--把其他学生选修结果课程数大于等于“0700001”学生的查出来

6.查询本月过生日的学生信息。
SELECT *
FROM Student
WHERE MONTH(birthday)=MONTH(GETDATE())
7.查询没有成绩的学生信息。(使用IN语句)
SELECT *
FROM Student
WHERE studentNo NOT IN(
						SELECT studentNo
						FROM Score)
8.查询(没有)选修过课程的学生姓名。(使用IN语句)
SELECT *
FROM Student
WHERE studentNo NOT IN(
						SELECT studentNo
						FROM Score )
9.查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩。 
SELECT Student.studentNo,studentName,AVG(score)AS '平均成绩'
FROM Student,Score
WHERE Student.studentNo=Score.studentNo
	AND Student.studentNo IN(
							SELECT studentNo
							FROM Score
							WHERE score<60
							GROUP BY studentNo
							HAVING COUNT(studentNo)>=2)
GROUP BY Student.studentNo,studentName

10.查找选修过课程名中包含“系统”的课程的同学学号、姓名和所在班级。
SELECT DISTINCT Score.studentNo,Student.studentName,classNo
FROM Student,Course,Score
WHERE courseName LIKE '%系统%'
	AND Course.courseNo=Score.courseNo
	AND Score.studentNo=Student.studentNo
11.查找同时选修过“高等数学”和“离散数学”两门课程的同学学号、姓名以及该同学所选修的所有课程的课程名和相应成绩,按学号(升序)、成绩(降序)排序输出。
SELECT Student.studentNo,studentName,courseName,score
FROM Student,Course,Score
WHERE Student.studentNo=Score.studentNo
	AND Score.courseNo=Course.courseNo
	AND Student.studentNo IN (
							SELECT Score.studentNo
							FROM Score,Course
							WHERE courseName='高等数学'
								AND Course.courseNo=Score.courseNo
								AND studentNo IN(
												SELECT Score.studentNo
												FROM Score,Course
												WHERE courseName='离散数学'
													AND Course.courseNo=Score.courseNo))
ORDER BY studentNo ASC,score DESC
12.查询所有学生的选修信息,显示信息包括学号,选修门数,平均分和总分。
SELECT studentNo,COUNT(courseNo)AS'选修门数',AVG(score)AS'平均分',SUM(score)AS'总分'
FROM Score
GROUP BY studentNo
13.查询先修课是“计算机基础”的课程。(分别用自连接和IN语句实现)
//自连接
SELECT studentNo
FROM Score,Course
WHERE courseName='计算机基础'
	AND Course.courseNo=Score.courseNo
//IN语句
SELECT studentNo
FROM Score
WHERE courseNo IN(
				SELECT courseNo
				FROM Course
				WHERE courseName='计算机基础')
14.查询至少有一门课程成绩超过85分的所有学生的信息,显示信息包括学号、课程号和分数。
SELECT  studentNo,courseNo,score
FROM Score
WHERE score>85
	AND studentNo IN(	
					SELECT studentNo
					FROM Score
					WHERE score>85)
15.查询至少有两门课程成绩超过85分的所有学生的学号。
SELECT studentNo
FROM Score
WHERE score>85
GROUP BY studentNo
HAVING COUNT(studentNo)>=2
16.查询平均成绩超过80分且选修3门及以上的所有学生的信息,显示信息包括学号、课程数目和分数。
SELECT studentNo,COUNT(courseNo)AS'课程数目',score
FROM Score
WHERE studentNo IN(
					SELECT studentNo
					FROM Score
					WHERE studentNo IN(
										SELECT studentNo
										FROM Score
										GROUP BY studentNo
										HAVING AVG(score)>80)
					GROUP BY studentNo
					HAVING COUNT(courseNo)>=3)
GROUP BY studentNo,score
17.查询所选修课程的成绩大于所有“002”号课程成绩的同学学号及相应课程的课程号和成绩。
//第一种
SELECT studentNo,courseNo,score
FROM Score
WHERE score >ALL(
				SELECT score
				FROM Score,Course
				WHERE Course.courseNo='002'
					AND Score.courseNo=Course.courseNo)
//第二种
SELECT studentNo,courseNo,score
FROM Score
WHERE score >(SELECT MAX(score)
			FROM Score
			WHERE courseNo='002')
18.查询选修了所有课程的学生姓名。
//第一种
SELECT Score.courseNo,Score.studentNo
FROM Score INNER JOIN Course
ON Course.courseNo=Score.courseNo
GROUP BY Score.courseNo,Score.studentNo
HAVING COUNT(Score.studentNo)=7
//第二种
SELECT studentName
FROM Student
WHERE NOT EXISTS(
				SELECT *
				FROM Course
				WHERE NOT EXISTS (
								SELECT *
								FROM Score
								WHERE studentNo =Student.studentNo
									AND courseNo=Course.courseNo))

2.2数据操纵

1.将所有选修001课程的同学的成绩增加5分。
UPDATE Score
SET score=score-5
WHERE courseNo='001'
2.将李小勇同学选修课程的成绩增加30%UPDATE Score,Student
SET score=score*1.3
WHERE studentName='李小勇'
	AND Student.studentNo=Score.studentNo
3.将每个班级的学生人数填入到班级表的ClassNum列中。
UPDATE Class
SET ClassNum=(
			SELECT COUNT(studentNo)
			FROM Student 
			WHERE classNo=Class.classNo)

4.在Student表中添加一条学生记录(学号:0800016,姓名:张三,籍贯:福建)INSERT INTO Student
VALUES('0800016','张三','','','福建','','')
5.求出每门课程的选修人数,把结果存放在新表CountC中。(SELECT  INTO语句实现)
SELECT courseNo,COUNT(studentNo)AS'选修人数'
INTO CountC
FROM Score
GROUP BY courseNo
6.求出每个学生的选修门数和平均分,把结果存放在新表CountSC中。(INSERT SELECT语句实现)
--建CountSC表
CREATE TABLE CountSC(
studentNo CHAR(7) NOT NULL,
选修门数 CHAR(7),
平均分 CHAR(50))
--添加数据到CountSC表
INSERT INTO CountSC
SELECT DISTINCT studentNo,COUNT(courseNo)AS'选修门数',AVG(score)AS'平均分'
FROM Score
GROUP BY studentNo
7.删除刘方晨同学所有的选修记录。
DELETE *
FROM Score
WHERE studentNo IN(
					SELECT studentNo
					FROM Student
					WHERE studentName='刘方晨')
8.删除选修了“操作系统”课程的选课记录。
DELETE *
FROM Score
WHERE courseNo IN(
					SELECT courseNo
					FROM Course
					WHERE courseName='操作系统')

2.3视图

1.创建视图vw1,该视图包含福建省的女学生信息。
CREATE VIEW vw1
AS
SELECT *
FROM Student
WHERE native='福建'
	AND sex='女'
2.创建视图vw2,该视图包含学生的学号、姓名、所选修的课程的课程号、课程名和成绩。
CREATE VIEW vw2
AS
SELECT Student.studentNo,studentName,Course.courseNo,courseName,score
FROM Student,Course,Score
WHERE Student.studentNo=Score.studentNo
	AND Score.courseNo=Course.courseNo
3.创建视图vw3,该视图每门课程的课程号、课程名、选修人数和平均分。
CREATE VIEW vw3
AS
SELECT Course.courseNo,Course.courseName,COUNT(studentNo)AS'选修人数',AVG(score)AS'平均分'
FROM Course,Score
WHERE Course.courseNo=Score.courseNo
GROUP BY Course.courseNo,Course.courseName
4.建立一个新的视图vw4,该视图包含学生姓名和年龄字段。将vw4中的年龄增加1岁。观察其运行结果并分析原因。
--建立一个新的视图vw4,该视图包含学生姓名和年龄字段
CREATE VIEW vw4(studentName,age)
AS
SELECT studentName,YEAR(GETDATE())-YEAR(birthday) age 
FROM Student
--将vw4中的年龄增加1岁。
UPDATE vw4
SET age=age+1
5.删除视图vw1中学号为 ‘0800007’ 的数据。
DELETE FROM vw1
WHERE studentNo='0800007'

三、解析

说明:只挑部分较难的题目来分析
相关理论知识参考:数据库系统概论(基础篇)-笔记

2.1数据查询

4.查询至少有一门课与学号为’0700001’的学生所学相同的学生的学号和姓名。

数据库系统原理--实验二 数据库定义与操作语言--习题答案_第5张图片
第一步:先在Score表中查询学号为“’0700001”选修的课程号;
第二步:再Score表中查询至少有一门课程号与第一步课程号相同的学生学号;
第三步:再Student表中查询与第二步学号相同的学生学号与姓名。
5.查询至少选修了学号为“0700001”学生所选修的所有课程的学生姓名。
暂时忘记怎么做了
6.查询本月过生日的学生信息。
数据库怎么查出本月过生日的同学

MONTH(birthday)=MONTH(GETDATE())

表示生日=当月的信息

MONTH(birthday)=MONTH(GETDATE())+1

表示生日=当前下一月的信息
9.查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩。

GROUP BY 需要与SELECT 的一致
数据库系统原理--实验二 数据库定义与操作语言--习题答案_第6张图片
平均成绩是原表中没有的属性,可以通过这个方式来创建。
数据库系统原理--实验二 数据库定义与操作语言--习题答案_第7张图片
17.查询所选修课程的成绩大于所有“002”号课程成绩的同学学号及相应课程的课程号和成绩。
如果成绩有空值的话,不能用ALL,要用MAX。

SELECT studentNo,courseNo,score
FROM Score
WHERE score >(SELECT MAX(score)
			FROM Score
			WHERE courseNo='002')

2.3视图

4.建立一个新的视图vw4,该视图包含学生姓名和年龄字段。将vw4中的年龄增加1岁。观察其运行结果并分析原因。

CREATE VIEW vw4(studentName,age)
AS
SELECT studentName,YEAR(GETDATE())-YEAR(birthday) age 
FROM Student

UPDATE vw4
SET age=age+1

因为所创建的视图对其属性值进行了计算的其他形式上的改变,
而对视图的更改最终表现为对表的更改而表中不存在视图的某一属性,或属性的性质不相同,
则无法更改,这是一种视图机制。
而且在我们数据库中存在的vw4的数据有两个,只不过一个是基本表,一个是视图。
视图里的数据是从该Student基本表中得出的数据,如果要修改视图,就转化为对Student表的修改,
但是在Student表中并没有age这列属性,所以无法更改。
解决办法是重新创建一个基本表vw5,结构内容都一样的,然后把vw4视图的数据添加到vw5基本表中,就可以修改年龄了。

CREATE TABLE vw5(
studentName VARCHAR(20) NOT NULL,
age VARCHAR(20)
)

INSERT INTO vw5
SELECT *
FROM vw4


UPDATE vw5
SET age=age+1

《推荐文章》
数据库系统概论(基础篇)-笔记
数据库系统概论(基础篇)–讨论答案
如何使用向导创建数据库和基本表结构?(SQL Server 2014)
使用数据库DDL语言创建数据库和基本表?(SQL Server 2014)

你可能感兴趣的:(数据库系统原理)