【数据库系统设计】关系数据库标准语言SQL(3)

之前的笔记戳这里,虽然实际项目中用不到这么多 sql 的知识点,但是记录一下,了解一下也OK。
【数据库系统设计】关系数据库标准语言SQL(1)
【数据库系统设计】关系数据库标准语言SQL(2)

数据更新

插入数据

插入元组

将新元组插入指定表中:

INSERT 
INTO <表名> [(<属性列1>[,<属性列2 >)] VALUES (<常量1> [,<常量2>]); 

EX:将一个新学生元组 (学号:201215128; 姓名:陈冬; 性别:男; 所在系:IS; 年龄:18岁) 插入到 Student 表中。

INSERT INTO Student (Sno, Sname, Ssex, Sdept, Sage) 
VALUES ('201215128','陈冬','男','IS',18); 

EX:将学生张成民的信息插入到Student表中。

NSERT INTO  Student 
VALUES ('201215126','张成民','男’,18,'CS'); 

EX:插入一条选课记录 (‘201215128’, ‘1’)。

# 关系数据库管理系统将在新插入记录的Grade列上自动地赋空值
INSERT INTO SC(Sno, Cno)
VALUES ('201215128', '1'); 
# 或者
INSERT INTO SC 		
VALUES ('201215128', '1', NULL); 

插入子查询结果

INSERT INTO <表名> [(<属性列1> [,<属性列2>)]

EX:对每一个系,求学生的平均年龄,并把结果存入数据库
第一步:建表

CREATE TABLE Dept_age
(Sdept CHAR(15), /*系名*/
Avg_age SMALLINT); /*学生平均年龄*/

第二步:插入数据

INSERT INTO Dept_age(Sdept, Avg_age)
	SELECT Sdept, AVG(Sage)
	FROM Student
	GROUP BY Sdept;

修改数据

UPDATE <表名>
SET <列名>=<表达式>[,<列名>=<表达式>][WHERE <条件>];

修改某一个元组值

Ex:将学生201215121的年龄改为22岁

UPDATE Student
SET Sage=22
WHERE Sno= '201215121';

Ex:将所有学生的年龄增加1岁。

UPDATE Student
SET Sage= Sage+1;

Ex:将计算机科学系全体学生的成绩置零。

UPDATE SC
SET Grade=0
WHERE Sno IN
(SELETE Sno
FROM Student
WHERE Sdept= 'CS');

删除数据

# 删除指定表中满足WHERE子句条件的元组
DELETE FROM <表名>
# WHERE子句指定要删除的元组,无该子句将会删除表中的全部元组
[WHERE <条件>];

删除某一个元组的值

Ex:删除学号为201215128的学生记录。

DELETE FROM Student
WHERE Sno=201215128';

Ex:删除计算机科学系所有学生的选课记录。

删除多个元组的值

Ex:
删除所有的学生选课记录。

DELETE FROM SC;

带子查询的删除语句

DELETE
FROM SC
WHERE Sno IN
(SELETE Sno
FROM Student
WHERE Sdept= 'CS') ;

空值的处理

空值的产生

  • 空值就是“不知道”或“不存在”或“无意义”的值。

  • 一般有以下几种情况:

    • 该属性应该有一个值,但目前不知道它的具体值
    • 该属性不应该有值
    • 由于某种原因不便于填写
  • 空值是一个很特殊的值,含有不确定性。
    对关系运算带来特殊的问题,需要做特殊的处理。

  • 空值的产生有其实际需求。
    学生在选课后,产生选课表,但是还没有成绩。这时候成绩部分就为空值,它和0不一样(不是0分)

Ex:向SC表中插入一个元组,学生号是”201215126”,课程号是”1”,成绩为空。

INSERT INTO SC(Sno, Cno, Grade)
VALUES('201215126', '1',NULL); /*该学生还没有考试成绩,取空值*/
# 或者
INSERT INTO SC(Sno, Cno)
VALUES(' 201215126', '1'); /*没有赋值的属性,其值为空值*/

Ex:将Student表中学生号为”201215200”的学生所属的系改为空值。

UPDATE Student
SET Sdept = NULL
WHERE Sno='201215200';

空值的判断

判断一个属性的值是否为空值,用IS NULLIS NOT NULL来表示。
Ex:找出漏填了性别或者年龄信息的记录。

SELECT *
FROM Student
WHERE Ssex IS NULL OR Sage IS NULL;

空值的约束条件

属性定义(或者域定义)中

  • NOT NULL约束条件的不能取空值
  • 加了UNIQUE限制的属性不能取空值
  • 主码属性不能取空值

空值的算术运算、比较运算和逻辑运算

  • 空值与另一个值(包括另一个空值)的算术运算的结果为空值
  • 空值与另一个值(包括另一个空值)的比较运算的结果为UNKNOWN
  • UNKNOWN后,传统二值(TRUEFALSE)逻辑就扩展成了三值逻辑

在这里插入图片描述

Ex:找出选修1号课程的不及格的学生。

SELECT Sno
FROM SC
WHERE Grade < 60 AND Cno='1';

查询结果不包括缺考的学生,因为他们的 Grade 值为null

Ex:选出选修1号课程的不及格的学生以及缺考的学生。

SELECT Sno
FROM SC
WHERE Cno='1' AND (Grade<60 OR Grade IS NULL);

聚集函数: MAX、MIN、AVG、COUNT、SUM 遇到空值时,除了COUNT(*)外,都跳过空值而去处理非空值。

视图

视图的特点

  • 虚表,是从一个或几个基本表(或视图)导出的表
  • 只存放视图的定义,不存放视图对应的数据
  • 基表中的数据发生变化,从视图中查询出的数据也随之改变

定义视图

CREATE VIEW
<视图名> [(<列名> [,<列名>])]
AS <子查询>
[WITH CHECK OPTION];
  • 关系数据库管理系统执行CREATE VIEW语句时只是把视图定义存入数据字典,并不执行其中的SELECT语句。
  • 在对视图查询时,首先判断视图是否存在,如果存在,则从数据字典中取出视图的定义,把定义中的子查询和对视图的查询结合起来,转换成等价的对基本表的查询。

在这里插入图片描述
Ex:建立信息系学生的视图。

CREATE VIEW IS_Student
AS
SELECT Sno,Sname,Sage
FROM Student
WHERE Sdept= 'IS';

Ex:建立信息系学生的视图,并要求进行修改和插入操作时仍需保证该视图满足信息系学生这个条件。

# IS_Student1视图是一个行列子集视图
CREATE VIEW IS_Student1
AS
SELECT Sno, Sname, Sage
FROM Student
WHERE Sdept= 'IS'
WITH CHECK OPTION;

基于多个表的视图

Ex:建立信息系选修了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';

基于视图的视图

Ex:建立信息系选修了1号课程且成绩在90分以上的学生的视图。

CREATE VIEW IS_S2
AS
SELECT Sno, Sname, Grade
FROM IS_S1
WHERE Grade >= 90;

带表达式的视图

Ex:定义一个反映学生出生年份的视图。

CREATE VIEW BT_S(Sno, Sname, Sbirth)
AS
SELECT Sno, Sname, 2014-Sage
FROM Student;

分组视图

Ex:将学生的学号及平均成绩定义为一个视图

CREATE VIEW S_G(Sno,Gavg)
AS
SELECT Sno,AVG(Grade)
FROM SC
GROUP BY Sno;

删除视图

DROP VIEW <视图名>[CASCADE];
  • 该语句从数据字典中删除指定的视图定义
  • 如果该视图上还导出了其他视图,使用CASCADE级联删除语句,把该视图和由它导出的所有视图一起删除
  • 删除基表时,由该基表导出的所有视图定义都必须显式地使用DROP VIEW语句删除

Ex:删除视图 BT_S 和 IS_S1。

DROP VIEW BT_S; /*成功执行*/
DROP VIEW IS_S1; /*拒绝执行*/

# 要删除IS_S1,需使用级联删除:
DROP VIEW IS_S1 CASCADE;

查询视图

用户角度:查询视图与查询基本表相同
关系数据库管理系统实现视图查询的方法

  • 视图消解法(View Resolution)
  • 进行有效性检查
  • 转换成等价的对基本表的查询
  • 执行修正后的查询

Ex:在信息系学生的视图中找出年龄小于20岁的学生。

SELECT Sno, Sage
FROM IS_Student
WHERE Sage<20;

视图消解转换后的查询语句为:

SELECT Sno, Sage
FROM Student
WHERE Sdept= 'IS' AND Sage<20;

Ex:查询选修了1号课程的信息系学生。

SELECT IS_Student.Sno, Sname
FROM IS_Student, SC
WHERE IS_Student.Sno = SC.Sno AND SC.Cno = '1';

Ex:在S_G视图中查询平均成绩在90分以上的学生学号和平均成绩。
S_G视图的定义如下:

CREATE VIEW S_G(Sno,Gavg)
AS
SELECT Sno,AVG(Grade)
FROM SC
GROUP BY Sno;

解法一:

# 视图查询
SELECT *
FROM S_G
WHERE Gavg>=90;

解法二:

# 视图消解法
# 错误:
SELECT Sno,AVG(Grade)
FROM SC
WHERE AVG(Grade)>=90
GROUP BY Sno;
# 正确:
SELECT Sno,AVG(Grade)
FROM SC
GROUP BY Sno
HAVING AVG(Grade)>=90;

解法三:

SELECT *
FROM (SELECT Sno,AVG(Grade) Gavg
FROM SC
GROUP BY Sno) AS S_G WHERE Gavg>=90;

更新视图

Ex:将信息系学生视图IS_Student中学号”201215125”的学生姓名改为”刘辰”。

UPDATE IS_Student
SET Sname= '刘辰'
WHERE Sno= '201215125';

# 转换后的语句
UPDATE Student
SET Sname= '刘辰'
WHERE Sno= '201215125' AND Sdept= 'IS';

Ex:向信息系学生视图IS_Student中插入一个新的学生记录,其中学号为”201215129”,姓名为”赵新”,年龄为20岁。

INSERT
INTO IS_Student
VALUES('201215129','赵新',20);
# 转换成对基本表的更新
INSERT
INTO Student(Sno,Sname,Sage,Sdept)
VALUES('200215129','赵新',20,'IS');
# 不同的系统处理方式不一样,MySQL会在系名处自动填入NULL或者默认值

在这里插入图片描述

更新视图的限制:一些视图是不可更新的,因为对这些视图的更新不能唯一地有意义地转换成对相应基本表的更新。

视图的作用

视图能够简化用户的操作

当视图中数据不是直接来自基本表时,定义视图能够简化用户的操作

  • 基于多张表连接形成的视图
  • 基于复杂嵌套查询的视图
  • 含导出属性的视图

视图使用户能以多种角度看待同一数据

视图机制能使不同用户以不同方式看待同一数据,适应数据库共享的需要

视图对重构数据库提供了一定程度的逻辑独立性

数据库重构 :

例:学生关系Student(Sno, Sname, Ssex, Sage, Sdept)“垂直”地分成两个基本表:SX(Sno, Sname, Sage),SY(Sno, Ssex, Sdept)

通过建立一个视图Student:

CREATE VIEW Student(Sno, Sname, Ssex, Sage, Sdept)
AS
SELECT SX.Sno, SX.Sname, SY.Ssex, SX.Sage, SY.Sdept
FROM SX,SY
WHERE SX.Sno=SY.Sno;

使用户的外模式保持不变,用户的应用程序通过视图仍然能够查找数据

视图能够对机密数据提供安全保护

对不同用户定义不同视图,使每个用户只能看到他有权看到的数据

适当的利用视图可以更清晰的表达查询

经常需要执行这样的查询 “对每个同学找出他获得最高成绩的课程号”。
可以先定义一个视图,求出每个同学获得的最高成绩

CREATE VIEW VMGRADE
AS
SELECT Sno, MAX(Grade) Mgrade
FROM SC
GROUP BY Sno;

然后用如下的查询语句完成查询:

SELECT SC.Sno, Cno
FROM SC, VMGRADE
WHERE SC.Sno = VMGRADE.Sno AND
SC.Grade = VMGRADE.Mgrade;
发布了170 篇原创文章 · 获赞 47 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_43734095/article/details/105047143