插入子查询结果
INSERT
INTO <表名> [(<属性列1> [,<属性列2>… )]
子查询;
【例3.72】对每一个系,求学生的平均年龄,并把结果存入数据库
该步骤可分为两步
第一步:建立表
CREATE TABLE Dept_age
(Sdept CHAR(15)
Avg_age SMALLINT);
第二步:
对Stduent表按系分组求平均年龄,再存入表
INSERT INTO Dept_age(Sdept,Avg_age)
SELECT Sdept,AVG(Sage)
FROM Student
GROUP BY Sdept;
修改数据
UPDATE <表名>
SET <列名>=<表达式>[,<列名>=<表达式>]…
[WHERE <条件>];
【例3.74】将学生201215121的年龄改为22岁。
UPDATE Student
SET Sage=22
WHERE Sno='201215121';
【例3.74】将所有学生的年龄增加1岁。
UPDATE Student
SET Sage=Sage+1;
【例3.75】将计算机科学系全体学生的成绩置零。
UPDATE SC
SET Grade=0
WHERE Sno IN
(SELECT Sno
FROM Student
WHERE Sdept='CS');
删除数据
DELETE
FROM <表名>
[WHERE <条件>];
【例3.76】删除学号为201215128的学生记录。
DELETE
FROM Student
WHERE Sno=201215128;
删除时注意完整性规则,解决方法见往期博客。
【例3.77】删除所有的学生选课记录。
DELETE
FROM SC;
【例3.78】删除计算机科学系所有学生的选课记录。
DELETE
FROM SC
WHERE Sno IN(
SELECT Sno
FROM Student
WHERE Sdept='CS');
【例3.79】向SC表中插入一个元组,学生号是”201215125”,课程号是”1”,成绩为空。
INSERT INTO SC(Sno,Cno,Grade)
VALUES('201215125','1',NULL);
或
INSERT INTO SC(Sno,Cno)
VALUES('201215125','1');
【例3.80】将Student表中学生号为”201215123”的学生所属的系改为空值。
UPDATE Student
SET Sdept = NULL
WHERE Sno='201215123';
【例3.81】从Student表中找出漏填了数据的学生信息。
SELECT *
FROM Student
WHERE Sname IS NULL OR Ssex IS NULL OR Sage IS NULL OR Sdept IS NULL;
【例3.82】 找出选修1号课程的不及格的学生。
SELECT Sno
FROM SC
WHERE Grade < 60 AND Cno='1';
不包括缺考学生。
【例3.83】选出选修1号课程的不及格的学生以及缺考的学生。
SELECT Sno
FROM SC
WHERE Grade < 60 AND Cno='1'
UNION
SELECT Sno
FROM SC
WHERE Grade IS NULL AND Cno='1'
或者
SELECT Sno
FROM SC
WHERE Cno='1' AND (Grade<60 OR Grade IS NULL);
建立视图
CREATE VIEW <视图名> [(<列名> [,<列名>]…)]
AS <子查询>
[WITH CHECK OPTION];
【例3.84】建立信息系学生的视图。
CREATE VIEW IS_Student
AS
SELECT Sno,Sname,Sage
FROM Student
WHERE Sdept= 'IS';
【例3.85】建立信息系学生的视图,并要求进行修改和插入操作时仍需保证该视图只有信息系的学生 。
CREATE VIEW IS_Student
AS
SELECT Sno,Sname,Sage
FROM Student
WHERE Sdept= 'IS'
WITH CHECK OPTION;
加上WITH CHECK OPTION子句,以后对该视图进行插入、修改和删除操作时,关系数据库管理系统会自动加上Sdept='IS’的条件。
【例3.86】建立信息系选修了1号课程的学生的视图(包括学号、姓名、成绩)。
CREATE VIEW IS_S1(Sno,Sname,Grade)
AS
SELECT Student.Sno,Sname,Grade
FROM Student,SC
WHERE Sdept='IS' AND Student.Sno=SC.Sno AND SC.Cno='1';
视图不仅可以建立在一个或多个基本表上,也可以建立在一个或多个已定义好的视图上,或建立在基本表与视图上。
【例3.87】建立信息系选修了1号课程且成绩在90分以上的学生的视图。
CREATE VIEW IS_S2
AS
SELECT Sno,Sname,Grade
FROM IS_S1
WHERE Grade>=90;
【例3.88】定义一个反映学生出生年份的视图。
CREATE VIEW BT_S(Sno,Sname,Sbirth)
AS
SELECT Sno,Sname,2020-Sage
FROM Student;
【例3.89】 将学生的学号及平均成绩定义为一个视图。
CREATE VIEW S_G(Sno,Gavg)
AS
SELECT Sno,AVG(Grade)
FROM SC
GROUP BY Sno;
【例3.90】将Student表中所有女生记录定义为一个视图。
CREATE VIEW F_Student(F_Sno,name,sex,age,dept)
AS
SELECT *
FROM Student
WHERE Ssex='女';
删除视图
DROP VIEW <视图名>[CASCADE];
如果该视图上还导出了其他视图,则使用CASCADE级联删除语句把该视图和由它导出的所有视图一起删除。
【例3.91】删除视图BT_S和IS_S1;
DROP VIEW BT_S; /*成功执行*/
DROP VIEW IS_S1;/*拒绝执行*/
IS_S2需使用级联删除
DROP VIEW IS_S1 CASCADE;
与之前的情况一样,SQL Sever不支持CASCADE关键字。
【例3.92】在信息系学生的视图中找出年龄小于20岁的学生。
SELECT Sno,Sage
FROM IS_Student
WHERE Sage<20;
关系数据库管理系统执行对视图的查询时,首先进行有效性检查,检查查询中涉及的表、视图等是否存在。如果存在,则从数据字典中取出视图的定义,把定义中的子查询和用户的查询结合起来,转换成等价的对基本表的查询,然后再执行修正了的查询。这一转换过程称为视图消解。
转换后的查询语句:
SELECT Sno,Sage
FROM Student
WHERE Sdept='IS' AND Sage<20;
【例3.94】在S_G视图中查询平均成绩在90分以上的学生学号和平均成绩
SELECT *
FROM S_G
WHERE Gavg>=90;
查询语句与定义S_G视图的字查询结合:
SELECT Sno,AVG(Grade)
FROM SC
WHERE AVG(Grade)>=90
GROUP BY Sno;
因为WHERE字句中是不能用聚集函数作为条件表达式的,因此执行此修正后的查询将会出现语法错误。
使用HAVING转换
SELECT Sno,AVG(Grade)
FROM SC
GROUP BY Sno
HAVING AVG(Grade)>=90;
利用派生表也可完成查询
SELECT *
FROM (SELECT Sno,AVG(Grade)
FROM SC
GROUP BY Sno) AS S_G(Sno,Gavg)
WHERE Gavg>=90;
【例3.95】将信息系学生视图IS_Student中学号”201215122”的学生姓名改为”刘辰”。
UPDATE IS_Student
SET Sname='刘辰'
WHERE Sno='201215122';
转换后:
UPDATE Student
SET Sname='刘辰'
WHERE Sno='201215122' AND Sdept='IS';
【例3.96】向信息系学生视图IS_S中插入一个新的学生记录,其中学号为”201215129”,姓名为”赵新”,年龄为20岁。
INSERT
INTO IS_Student
VALUES('201215129','赵新',20);
转换为对基本表的更新:
INSERT
INTO Student(Sno,Sname,Sage,Sdept)
VALUES('200215129','赵新',20,'IS' );
【例3.97】删除信息系学生视图IS_Student中学号为”201215129”的记录
DELETE
FROM IS_Student
WHERE Sno= '201215129';
转换为对基本表的更新:
DELETE
FROM Student
WHERE Sno= '201215129' AND Sdept='IS';