第三章关系数据库标准语言
一.结构化查询语言概述
SQL,结构化查询语言,是关系数据库的标准语言,是一个通用的、功能强大的关系数据库标准语言。
1.1SQL的产生与发展
SQL最早由IBM在20世纪70年代开发,并作为SystemR项目的一部分。随着SQL的发布,几乎所有的数据库产品都支持SQL,并对SQL进行了扩充与修改,SQL成为当前应用最为广泛的关系数据语言。
现在SQL已经成为了一种标准,常用的Oracle,SQL Server,MySQL,DB2,Ingres以及中型数据库产品对SQL的支持大部分相似,但它们之间存在着一定的差异,与SQL标准的符合程度不相同,一般在85%以上。
1.2SQL的特点
1.一体化
SQL集数据定义语言(DDL)、数据操纵语言(DDL)、数据控制语言(DCL)功能于一体,语言风格统一,能够独立完成数据库应用系统的全部需要。
2.高度非过程化
SQL是一种高度的非过程化语言,用户无须了解具体的操作过程及存取路径的选择,由数据库管理系统自动完成全部工作。
3.面向集合的操作(采用集合操作方式)
每个命令的操作对象是一个或多个关系,结果仍是一个关系,一次插入、删除和更新操作的对象也可以是元组的集合。
4.提供多种使用方式
既是独立语言、又是嵌入式语言。
5.功能强大,简洁易用
只用9个动词即可完成核心功能。
SQL语句动词
1.3SQL与数据库三级模式
1.1.1基本表
基本表是一个独立的表。一个或多个基本表对应一个存储文件,一个基本表上可以建立多个索引,索引也存放在存储文件中。
1.1.2视图(虚表)
从一个或几个基本表导出的表。数据库中只存放视图的定义而不存放数据。
因此,基本表中数据发生改变时,从视图查询出的数据也随着改变,
用户可以使用SQL语言定义的视图,也可以在视图上再定义视图。
1.1.3存储文件
存储文件的逻辑结构组成了关系数据库的内模式,其物理结构对最终用户是隐蔽的。用户可以用SQL语句对视图和基本表进行查询等操作。
1.1.4SQL用户(应用程序OR终端用户)
SQL可以作为独立的用户接口,供终端用户在交互环境下使用,也可以嵌入在程序设计语言中使用。
二数据定义
SQL的数据定义功能包括对数据库模式、基本表、视图、索引的创建和删除。
2.1模式的定义和删除
2.1.1模式的创建
创建一个SQL模式就是定义了一个命名空间,并包含模式中基本表、视图、索引等数据库对象的定义。一个感谢数据库管理系统的实例中可以建立多个数据库,一个数据库中可以建立多个模式。
SQL中,一个模式由模式名和模式拥有者确定。
创建模式语句:
C
R
E
A
T
E
S
C
H
E
M
A
<
模式名
>
<
C
A
S
C
D
E
∣
R
E
S
T
R
I
C
T
>
;
CREATE \quad SCHEMA <模式名><CASCDE\mid RESTRICT>;
CREATESCHEMA<模式名><CASCDE∣RESTRICT>;
大部分DBMS不采用‘模式’这个名词,而是采用“数据库”(DATABASE),在DBMS中创建模式用“CREATE DATABASE”。
2.1.2删除模式
当一个模式及其所属的表、视图等对象都不需要是,可以用DROP语句删除。
DROP语句:
D
R
O
P
S
C
H
E
M
A
<
模式名
>
<
C
A
S
C
A
D
E
∣
R
E
S
T
R
I
C
T
>
;
DROP \quad SCHEMA <模式名><CASCADE\mid RESTRICT>;
DROPSCHEMA<模式名><CASCADE∣RESTRICT>;
<CASCADE|RESTRICT>两者必选一:CASCADE(级联)表示删除模式的同时把该模式中的所有数据库对象全部删除。RESTRICT(限制)表示如果该模式中定义了下属的数据库对象(如表、视图等),则拒绝该语句的执行;当该模式中没有任何下属的对象时执行。
2.2基本表的定义、删除和修改
创建一个模式就是建立了一个数据库的命名空间。在这个空间中定义所包含的对象,如表、视图、索引等。
2.2.1定义基本表
C
R
E
A
T
E
T
A
B
L
E
<
表名
>
(
<
列名
>
<
数据类型
>
[
<
列级完整性约束条件
>
]
,
<
列名
>
<
数据类型
>
[
<
列级完整性约束条件
>
]
,
[
<
表级完整性约束条件
>
]
)
;
CREATE \quad TABLE <表名> \\ (<列名>\quad <数据类型>[<列级完整性约束条件>],\\<列名> \quad <数据类型>[<列级完整性约束条件>],\\ [<表级完整性约束条件>] );
CREATETABLE<表名>(<列名><数据类型>[<列级完整性约束条件>],<列名><数据类型>[<列级完整性约束条件>],[<表级完整性约束条件>]);
其中,<表名>是合法标识符,尖括号表示必选项,方括号表示可选项,一个表至少包含一列。如果完整性约束条件涉及表的多个属性列时,则必须定义在表级上,否则既可以定义在列级也可以定义在表级。完整性约束有以下几种。
NOT NULL:限制列取值非空。
DEFAULT:指定列的默认值。
UNIQUE:限制列取值不能重复。
CHECK:限制列的取值范围。
PRIMARY KEY:指定本列为主码。
FOREIGNKEY:定义本列为引用其他表的外码。
使用形式为:
F
O
R
E
I
G
N
K
E
Y
(
<
外码列名
>
)
R
E
F
E
R
E
N
C
E
S
<
主码所在
表名
>
(
<
主码列名
>
)
FOREIGN \quad KEY(<外码列名>) \quad REFERENCES\ <主码所在\\表名>(<主码列名>)
FOREIGNKEY(<外码列名>)REFERENCES <主码所在表名>(<主码列名>)
2.2.2修改基本表
A
L
T
E
R
T
A
B
L
E
<
表名
>
[
A
L
T
E
R
C
O
L
U
M
N
<
列名
>
<
新数据类型
>
]
∣
[
A
D
D
[
C
O
L
U
M
N
]
<
列名
>
<
数据类型
>
]
∣
[
D
R
O
P
C
O
L
U
M
N
<
列名
>
]
∣
[
A
D
D
P
R
I
M
A
R
Y
K
E
Y
(
列名
[
,
…
n
]
)
]
[
A
D
D
F
O
R
E
I
G
N
K
E
Y
(
列名
)
R
E
F
E
R
N
E
C
E
S
表名
(
列名
)
]
;
ALTER\quad TABLE <表名>\\ [ALTER\quad COLUMN<列名><新数据类型>]\\ |[ADD [COLUMN]\quad <列名><数据类型>]\\ |[DROP\quad COLUMN<列名>]\\ | [ADD\quad PRIMARY KEY(列名[,… n])]\\ [ADD\quad FOREIGN\quad KEY(列名)\quad REFERNECES\quad 表名(列名)];
ALTERTABLE<表名>[ALTERCOLUMN<列名><新数据类型>]∣[ADD[COLUMN]<列名><数据类型>]∣[DROPCOLUMN<列名>]∣[ADDPRIMARYKEY(列名[,…n])][ADDFOREIGNKEY(列名)REFERNECES表名(列名)];
注意:在实际的DBMS中往往有以下限制:
(1)不能改变列名。
(2)不能将含有空值的列修改为 NOT NULL 约束。
(3)若列中已有数据,则不允许减小该列的宽度,也不能修改其数据类型。
(4)除NULL/NOT NULL约束之外,其类型的约束在修改之前必须先将其刪除
2.2.3删除基本表
D R O P T A B L E < 表名 > [ R E S T R I C T ∣ C A S C A D E ] DROP\quad TABLE\quad <表名>\quad [RESTRICT\mid CASCADE] DROPTABLE<表名>[RESTRICT∣CASCADE]
2.3索引的创建与删除
查询操作是数据库中最常用的操作
目的:为了提高查询速度
SQL标准和现在的DBMS都使用索引技术。
2.3.1.索引的创建
创建索引的语句格式为:
C
R
E
A
T
E
[
U
N
I
Q
U
E
]
[
C
L
U
S
T
E
R
]
I
N
D
E
X
<
索引名
>
O
N
<
表名
>
(
<
列名
>
[
<
次序
>
]
[
,
<
列名
>
[
<
次序
>
」
]
…
)
;
CREATE[UNIQUE][CLUSTER]\quad INDEX<索引名>ON{<表名>}\\ (<列名>[<次序>][,<列名>[<次序>」]… );
CREATE[UNIQUE][CLUSTER]INDEX<索引名>ON<表名>(<列名>[<次序>][,<列名>[<次序>」]…);
说明:
(1)可选项[UNIQUE]表示建立唯一索引。该索引的每一个索引值只能对应唯一的组,因此唯一索引常用于PRIMARYKEY的列上,以区别每一行。
(2)可选项[CLUSTER]表示建立聚簇索引。按照索引值排列元组,并将排好顺序的元组存储在表中。**一个表最多只能建立一个聚簇索引。**当表中有一个被设置UNIQUE的列时,系统会自动建立一个非聚簇的唯一索引。非聚簇索引的排列结果不会在储在表中,而是另外存储,所以一个表可以有多个非聚簇索引。而聚簇索引比非聚簇索引询速度快。DBMS一般会自动地在PRIMARYKEY的列上建立聚簇索引。
(3)必选项<索引名>是为创建的索引命名一个合法的标识符。
(4)必选项<表名>是指定要建立索引的基本表名字。
(5)<列名>表示要建立索引的列。索引可以建立在一列或多列上,各列之间用逗号久隔。每个<列名>后面还可以用<次序>指定索引值的排列次序。次序有升序和降序两种,ASC表示升序,DESC表示降序,默认值为ASC。
(6)只有DBA或表的主人(即建立表的人)才能建立索引。索引并不是建的越多越好系统维护索引顺序要花费代价,一般原则是在经常查询的列上建立索引,经常更新的列不宜建立聚簇索引。
(7)在查询时DBMS自动选择是否使用索引以及使用哪些索引。
(8)RDBMS中索引一般采用B+树、HASH索引来实现,B+树索引具有动态平衡优点,而HASH索引具有查找速度快的特点,是采用B十树,还是采用HASH索引,这由具体的RDBMS来决定。 索引是关系数据库的内部实现技术,属于内模式的范畴。
2.3.2删除索引
建立索引是为了提高查询速度,但随着索引的增多,数据更新时,DBMS要花费许多时间来维护索引。这就需要删除不必要的索引。
删除索引的语句格式为:
D
R
O
P
I
N
D
E
X
[
表名
.
索引名
]
;
DROP\quad INDEX \quad [表名.索引名];
DROPINDEX[表名.索引名];
删除索引时,系统会从数据字典中删除有关该索引的定义。
三.数据查询
数据查询是数据库中最常见的操作,通过SQL提供的SELECT语句进行操作课得到所需的信息。
3.1SELECT语句格式
SQL的查询语句一般格式为:
S
E
L
E
C
T
[
A
L
L
∣
D
I
S
T
I
N
C
T
]
<
目标列表达式
>
[
,
<
目标列表达式
>
]
.
.
.
F
R
O
M
<
表名或视图名
>
[
,
<
表名或视图名
>
]
.
.
.
[
W
H
E
R
E
<
条件表达式
>
]
[
G
R
O
U
P
B
Y
<
列名
1
>
[
H
A
V
I
N
G
<
条件表达式
>
]
[
O
R
D
E
R
B
Y
<
列名
2
>
[
A
S
C
∣
D
E
S
C
]
]
;
SELECT\quad[ALL\mid DISTINCT]<目标列表达式>{[,<目标列表达式>]}...\\FROM<表名或视图名>[,<表名或视图名>]...\\ [WHERE<条件表达式>]\\ [GROUP \quad BY<列名1>[HAVING<条件表达式>]\\ [ ORDER \quad BY <列名2>[ ASC|DESC ]];
SELECT[ALL∣DISTINCT]<目标列表达式>[,<目标列表达式>]...FROM<表名或视图名>[,<表名或视图名>]...[WHERE<条件表达式>][GROUPBY<列名1>[HAVING<条件表达式>][ORDERBY<列名2>[ASC∣DESC]];
说明:
(1)可选项[ALLIDISTINCT]:ALL表示输出全部查询结果,DISTINCT 表示取掉查询结果中的重复行,默认为 ALL。
(2)目标列表达式:表示要查询的数据,可以是列名、含有列名的函数或表达式,还可以是常量。
(3)<表名或视图名>:表示数据来源,可以是一个或两个以上的基本表或视图。
(4)可选项WHERE<条件表达式>子句:表示选取满足条件的元组。
(5)可选项GROUP BY<列名1>[HAVING<条件表达式>]子句:表示将查询结果按照<列名1>分组,值相同的元组被分为一组。HAVING<条件表达式>是对组的条件限制,只输出满足条件的组,它不能单独使用,只能配合GROUP BY子句。
(6)可选项ORDERBY<列名2>子句:表示将查询的结果按照<列名2>的值排序辖出,ASC表示升序,DESC表示降序,默认是升序。也可以按多个列排序,之间用逗号分隔。(7)SELECT语句执行的结果仍是一个表。SELECT子句相当于关系代数中的投影WHERE子句相当于选择操作,当查询涉及多个表时,WHERE子句要同时给出连接条件SELECT语句的执行顺序是FROM→WHERE→GROUP BY→SELECT→ORDER。
3.2单表查询
3.2.1选择表中若干列
1.选择表中若干列
1.1查询指定列
在实际应用中,用户可能只需要表中部分属性列,这时使用SELECT子句的<目标列表达式>指定。
eg:查询全体学生学号,姓名,出生日期
SELECT Sno,Sname,Sbirth
FROM S;
用户可以根据应用的需要改变<目标列表达式>中各个列的先后顺序。
2.查询全部列
查询全部列有两种方法:一种是在<目标列表达式>中全部列出;另一种是若列的显示顺序与其在表中的顺序相同,则可以简单地将<目标列表达式>指定为*。
eg:查询全体学生的详细信息。
S
E
L
E
C
T
S
n
o
,
S
n
a
m
e
,
S
s
e
x
,
S
b
i
r
t
h
,
S
d
e
p
t
F
R
O
M
S
SELECT \quad Sno, Sname, Ssex, Sbirth, Sdept\\ FROM\quad S
SELECTSno,Sname,Ssex,Sbirth,SdeptFROMS
等价于语句:
S
E
L
E
C
T
∗
F
R
O
M
S
;
SELECT\quad *\quad FROM\quad S;
SELECT∗FROMS;
3.查询经过计算的列
eg:查询全体学生的姓名以及年龄。
S
E
L
E
C
T
S
n
a
m
e
,
Y
e
a
r
(
C
U
N
R
D
A
T
E
(
)
)
−
Y
e
a
r
(
S
b
r
i
t
h
)
F
R
O
M
S
SELECT \quad Sname,Year(CUNRDATE()) - Year(Sbrith)\\ FROM\quad S
SELECTSname,Year(CUNRDATE())−Year(Sbrith)FROMS
这里通过函数获取当前日期的年份减去出生日期的年份计算得到学生年龄,MySQL为例,使用函数YEAR()取日期型数据的年份,CURDATE()取当前日期进行算。
SELECT 子句的<目标列表达式>可以是算术表达式、字符串常量、函数等,如果<目标列表达式>是字符串常量,则原样输出。用户还可以指定别名来改变查询结果的列标题,这对<目标列表达式>非常有用。
指定列别名的语法格式为:
<
目标列表达式
>
[
a
s
]
别名
<目标列表达式>[as]别名
<目标列表达式>[as]别名
以上个例子为例的查询结果指定列名:
S
E
L
E
C
T
S
n
a
m
e
a
s
姓名
,
Y
e
a
r
(
C
U
R
D
A
T
E
(
)
)
−
Y
e
a
r
(
S
b
i
r
t
h
)
a
s
年龄
F
R
O
M
S
SELECT\quad Sname\quad as\quad 姓名,Year(CURDATE())-Year(Sbirth )\quad as \quad 年龄\\ FROM\quad S
SELECTSnameas姓名,Year(CURDATE())−Year(Sbirth)as年龄FROMS
4.消除取值重复的行
在对表进行列的选择后,查询结果中可能会出现取值完全相同的行,可以用DISTINCT 消除它们。
eg:查询选修了课程的学生学号
S
E
L
E
C
T
S
n
o
F
R
O
M
S
C
;
SELECT\quad Sno\\ FROM\quad SC;
SELECTSnoFROMSC;
上述查询结果中会出现许多重复行,要取消掉这些重复行,必须在SELECT后面加上DISTINCT。
S
E
L
E
C
T
D
I
S
T
I
N
C
T
S
n
o
F
R
O
M
S
C
;
SELECT\quad DISTINCT\quad Sno\\ FROM\quad SC;
SELECTDISTINCTSnoFROMSC;
3.2.2选择表中若干元组
在查询中用户除了选择所需列之外,还可以对数据进行选择,通过WHERE字句实现。
WHERE字句常用的查询条件
查询条件 | 谓词 |
---|---|
比较 | = , > , < , > = , < = , < > , ! > , ! < ; N O T + 上述比较运算符 =,>,<,>=,<=,<>,!>,!<;NOT+上述比较运算符 =,>,<,>=,<=,<>,!>,!<;NOT+上述比较运算符 |
确定范围 | B E T W E E N A N D , N O T B E T W E E N A N D BETWEEN\quad AND,NOT\quad BETWEEN\quad AND BETWEENAND,NOTBETWEENAND |
确定集合 | I N , N O T I N IN,NOT\quad IN IN,NOTIN |
字符匹配 | L I K E , N O T L I K E LIKE,NOT\quad LIKE LIKE,NOTLIKE |
空值 | I S N U L L , I S N O T N U L L IS\quad NULL,IS\quad NOT\quad NULL ISNULL,ISNOTNULL |
多重条件 | A N D , O R , N O T AND,OR,NOT AND,OR,NOT |
1.比较大小
eg:查询软件工程系的学生学号及姓名
S
E
L
E
C
T
S
n
o
,
S
n
a
m
e
F
R
O
M
S
W
H
E
R
E
S
d
e
p
t
=
′
软件工程
系
′
;
SELECT\quad Sno,\quad Sname\\ FROM\quad S\\ WHERE\quad Sdept='软件工程系';
SELECTSno,SnameFROMSWHERESdept=′软件工程系′;
eg:查询2002年1月1日以后出生的学生姓名及出生日期
S
E
L
E
C
T
S
n
a
m
e
姓名
,
S
b
i
r
t
h
出生日期
F
R
O
M
S
W
H
E
R
E
S
b
i
r
t
h
>
′
2011
−
11
−
1
1
′
;
SELECT\quad Sname \quad 姓名,\quad Sbirth\quad 出生日期\\FROM\quad S\\WHERE\quad Sbirth>'2011-11-11';
SELECTSname姓名,Sbirth出生日期FROMSWHERESbirth>′2011−11−11′;
eg:查询考试成绩不及格的学生学号
S
E
L
E
C
T
D
I
S
T
I
N
C
T
S
n
o
F
R
O
M
S
C
W
H
E
R
E
G
r
a
d
e
<
60
;
SELECT\quad DISTINCT\quad Sno\\FROM\quad SC\\WHERE\quad Grade < 60 ;
SELECTDISTINCTSnoFROMSCWHEREGrade<60;
2.确定范围
确定范围使用谓词BETWEEN AND和NOT BETWEENN AND,查找属性值在(或不在)指定范围内的元组。其中,BETWEEN后面是下限(低值),AND后面是上限(高值其语法格式为:
列名
∣
<
表达式
>
[
N
O
T
]
B
E
I
W
E
E
N
<
下限
>
A
N
D
<
上限
>
列名\mid <表达式>[NOT]\quad BEIWEEN\quad <下限>\quad AND\quad {<上限>}
列名∣<表达式>[NOT]BEIWEEN<下限>AND<上限>
【例3-21】查询考试成绩为80~90的学生学号和课程号
S
E
L
E
C
T
S
n
o
,
C
n
o
F
R
O
M
S
C
W
H
E
R
E
G
r
a
d
e
B
E
T
W
E
E
N
80
A
N
D
90
;
SELECT\quad Sno, Cno\\ FROM\quad SC\\ WHERE\quad Grade\quad BETWEEN\quad 80\quad AND\quad 90 ;
SELECTSno,CnoFROMSCWHEREGradeBETWEEN80AND90;
等价于:
S
E
L
E
C
T
S
n
o
,
C
n
o
F
R
O
M
S
C
W
H
E
R
E
G
r
a
d
e
>
=
80
A
N
D
G
r
a
d
e
<
=
90
;
SELECT\quad Sno, \quad Cno\\ FROM\quad SC\\ WHERE\quad Grade\quad > =\quad 80\quad AND\quad Grade\quad <= \quad90;
SELECTSno,CnoFROMSCWHEREGrade>=80ANDGrade<=90;
3.确定集合
确定某个属性的值是否在指定的集合内使用IN谓词。
其语法格式为:
列名
[
N
O
T
]
I
N
(
常量
1
,常量
2
,
…
,常量
n
)
\quad 列名\quad[NOT]\quad IN(常量1,常量2,…,常量n)
列名[NOT]IN(常量1,常量2,…,常量n)
eg:查询计算机科学系、软件工程系和网络工程系的学生学号和姓名
S
E
L
E
C
T
S
n
o
,
S
n
a
m
e
F
R
O
M
S
W
H
E
R
E
S
d
e
p
t
I
N
(
′
计算机科学系’,软件工程
系
′
,网络工程
系
′
)
;
SELECT\quad Sno,\quad Sname\\FROM\quad S\quad WHERE\quad Sdept\quad IN('计算机科学系’,软件工程系',网络工程系');
SELECTSno,SnameFROMSWHERESdeptIN(′计算机科学系’,软件工程系′,网络工程系′);
等价于:
S
E
L
E
C
T
S
n
o
,
S
n
a
m
e
F
R
O
M
S
W
H
E
R
E
S
d
e
p
t
=
′
计算机科学
系
′
O
R
S
d
e
p
t
=
′
软件工程
系
′
O
R
S
d
e
p
t
=
′
网络工程
系
′
SELECT\quad Sno,\quad Sname\\ FROM\quad S\\ WHERE\quad Sdept='计算机科学系'\quad OR\quad Sdept='软件工程系'\quad OR\quad Sdept='网络工程系'
SELECTSno,SnameFROMSWHERESdept=′计算机科学系′ORSdept=′软件工程系′ORSdept=′网络工程系′
4.字符匹配
在实际查询中用户可能不能给出精确字符条件,这时就使用LIKE谓词和通配符来实现模糊查询。
其语法格式如下:
列名
[
N
O
T
]
L
I
K
E
′
<
匹配串
>
’
[
E
S
C
A
P
E
<
′
换码字
符
′
>
]
列名\quad [NOT]\quad LIKE\quad\ '<匹配串>’ \quad [ESCAPE<'换码字符'>]
列名[NOT]LIKE ′<匹配串>’[ESCAPE<′换码字符′>]
其含义是查找特定的属性列值与<匹配串>相匹配的元组。西配市中可以包含字符常量、也可包含下列通配符:%:匹配0个或多个任意字符。:匹配任意一个字符。
eg:查询姓“刘”的学生信息。
S
E
L
E
C
T
∗
F
R
O
M
S
W
H
E
R
E
S
n
a
m
e
L
I
K
E
′
刘
%
′
;
SELECT\quad *\\FROM\quad S\\WHERE\quad Sname\quad LIKE\quad\ '刘\%';
SELECT∗FROMSWHERESnameLIKE ′刘%′;
eg:查询姓名中最后一个字是“玲”的学生信息。
S
E
L
E
C
T
∗
F
R
O
M
S
W
H
E
R
E
S
n
a
m
e
L
I
K
E
′
%
玲
′
;
SELECT\quad *\\FROM\quad S\\ WHERE\quad Sname\quad LIKE\quad\ '\%玲';
SELECT∗FROMSWHERESnameLIKE ′%玲′;
eg:查询姓名中第二个字是“文”的学生信息。
S
E
L
E
C
T
∗
F
R
O
M
S
W
H
E
R
E
S
n
a
m
e
L
I
K
E
′
_
文‘
;
SELECT\quad *\\FROM\quad S\\ WHERE\quad Sname\quad LIKE\quad\ '\_文‘;
SELECT∗FROMSWHERESnameLIKE ′_文‘;
注意:数据库字符集为GBK时一个汉字只需要一个“”;当字符集为 ASCII 时一个汉字需要两个“_”。
5.涉及空值的查询
空值(NULL)在数据库中表示不确定或不知道的值。判断某个属性的值是否为NULL,不能使用比较运算符=或!=,只能使用IS NULL或IS NOT NULL谓词.
其语法格式:
列名
I
S
[
N
O
T
]
N
U
L
L
;
列名\quad IS\quad [NOT]\quad NULL;
列名IS[NOT]NULL;
eg:查询没有考试成绩的学生学号和相应的课程号.
S
E
L
E
C
T
S
n
o
,
C
n
o
F
R
O
M
S
C
W
H
E
R
E
G
r
a
d
e
I
S
N
U
L
L
;
SELECT\quad Sno, Cno\\FROM\quad SC\\WHERE\quad Grade\quad IS\quad NULL;
SELECTSno,CnoFROMSCWHEREGradeISNULL;
6.多重条件查询
在WHERE子句中可以用AND和OR运将多个条件连接起来查询。
eg:查询汉语言文学2002年1月1日以后出生的学生姓名及出生日期
S
E
L
E
C
T
S
n
a
m
e
,
S
b
r
i
t
h
F
R
O
M
S
W
H
E
R
E
S
d
e
p
t
=
′
汉语言文
学
′
A
N
D
S
b
r
i
t
h
>
′
2002
−
01
−
0
1
′
;
SELECT\quad Sname,Sbrith\\ FROM\quad S\\ WHERE\quad Sdept='汉语言文学'\quad AND\quad Sbrith>'2002-01-01';
SELECTSname,SbrithFROMSWHERESdept=′汉语言文学′ANDSbrith>′2002−01−01′;
3.3.3对查询结果排序
用户可以使用ORDERBY子句将查询的结果按照一列或多列排序输出。
语句格式如下:
O
R
D
E
R
B
Y
<
列名
1
>
[
,
<
列名
2
>
[
A
S
C
∣
D
E
S
C
]
]
ORDER\quad BY\quad <列名1>[,<列名2>[ASC\mid DESC]]
ORDERBY<列名1>[,<列名2>[ASC∣DESC]]
ASC表示升序,DESC表示降序,默认是升序,多列排序时之间用逗号分隔。
当排序含空值时:
ASC:排序列为空值的元组最后显示。
DESC:排序列为空值的元组最先显示。
eg:查询选修了课程号为“002”的学生学号及成绩,查询结果按成绩的降序排列。
S
E
L
E
C
T
S
n
o
,
G
r
a
d
e
F
R
O
M
S
C
W
H
E
R
E
C
n
o
=
′
00
2
′
O
R
D
E
R
B
Y
G
r
a
d
e
D
E
S
C
;
SELECT\quad Sno, Grade\\FROM\quad SC\\WHERE\quad Cno = '002'\\ORDER\quad BY\quad Grade\quad DESC;
SELECTSno,GradeFROMSCWHERECno=′002′ORDERBYGradeDESC;
3.3.4使用聚集函数统计汇总查询
SQL提供了许多库函数、用于统计和汇总查询,增加了基本检索能力。这些的函数是对给定值进行计算并返回一个单值,因此称之为聚集函数或集合函数。
常用的聚集函数及其功能
说明:除COUNT(*)外,其他函数在计算过程中均忽略NULL值;聚集函数不能用WHERE子句,只用于对整个表的计算和GROUP BY 和 HAVING 子句中。
3.3.5分组查询
GROUPBY子句按某一列或多列分组,细化聚集函数的作用对象:
未对查询结果分组,聚集函数将作用域整个查询结构;
对查询结果分组后,聚集函数将分别作用于每个组;
作用对象是查询的中间结果表;
按指定的一列或多列分组,值相等的为一组。
语法格式:
G
R
O
U
P
B
Y
<
分组列名
1
>
[
,
<
分组列名
1
>
.
.
.
]
[
H
A
V
I
N
G
<
组的筛选条件
>
]
GROUP\quad BY\quad <分组列名1>\quad [,<分组列名1>...][HAVING<组的筛选条件>]
GROUPBY<分组列名1>[,<分组列名1>...][HAVING<组的筛选条件>]
HAVING子句不能单独使用,只能配合GROUP BY子句,但GROUP BY子句可以没有HAVING子句:
HAVING子句与WHERE子句区别:HAVING子是对组的筛选条件;WHERE子是对表或视图中元组的筛选条件。
当在一个SQL查询中同时使用WHERE子句和GROUPBY子句时,其顺序是WHERE,GROUP BY,HAVING,所以GROUP BY子句一般跟在 WHERE 子句后面。
eg:查询选修两门及以上课程的学生学号和选课门数
S
E
L
E
C
T
S
n
o
学号
,
C
O
U
N
T
(
∗
)
选课门数
F
R
O
M
S
C
G
R
O
U
P
B
Y
S
n
o
H
A
V
I
N
G
(
C
O
U
N
T
(
∗
)
>
=
2
)
SELECT\quad Sno\;学号,COUNT(*)\;选课门数\\FROM\quad SC\\GROUP\quad BY\quad Sno\quad HAVING\quad (COUNT( *)>= 2)
SELECTSno学号,COUNT(∗)选课门数FROMSCGROUPBYSnoHAVING(COUNT(∗)>=2)
处理过程:先执行GROUPBY子句对SC表数据按Sno进行分组,然后用COUNT分别对每一组进行统计,最后按条件筛选出统计结果大于或等于2的组并输出。
3.3多表查询
连接查询:同时涉及两个以上的表的查询。
连接条件或连接谓词:用来连接两个表的条件
连接方法:
(1)表之间满足一定条件的行进行连接时,在FROM子旬中指明进行连接的表名,在WHERE子旬中指明连接的列名及连接条件。
INNERJOIN(内连接):显示符合条件的元组,系统默认内连接。LEFT(OUTER)JOIN;左外连接,用于显示符合条件的数据行以及左边表中不符合
(2)利用关健字JOIN进行连接。又分为以下几种。
RIGHT(OUTER)JOIN;右外连接,用于星示符合条件的数据行以及右边表中不符合条件的数据行,相应的左边数据行以 NUL1.来显示。FULL(OUTER)JOIN;完全连接,显示符合条件的数据行以及左边表和右边表中不合条件的数据行。此时相应的数据行都以 NULL来显示,
件的数据行,相应的右边数据行以 NULL来显示。
CROSSJOIN为交叉连接,将一个表的每一个元组和另一表的每个元组匹配成新的元组连接查询包括等值连接查询、自然连接查询,自身连接查询、外连接查询和复合条件接查询等。
3.3.1等值连接和非等值连接
一般格式为:
[
<
表名
1
>
,
]
<
列名
1
>
<
比较运算符
>
[
<
表名
2
>
]
<
列名
2
>
[<表名1>,]<列名 1>\quad <比较运算符>\quad [<表名 2>]<列名 2>
[<表名1>,]<列名1><比较运算符>[<表名2>]<列名2>
比较运算符主要有:
=
,
>
,
<
,
>
=
,
<
=
,
!
=
等
=,>,<,>=,<=,!=等
=,>,<,>=,<=,!=等
连接字段:连接谓词中的列名称
**连接条件中的列名称为连接字段,其必须有可比性,名字不一定相同。**当两个表的列名相同时·必须用表名前级来指明所属的表。如果列名是唯一的,则不必加前缀
eg:查询所有选课学生及其选课信息。
第一种写法
:
S
E
L
E
C
T
S
.
∗
,
S
C
.
∗
F
R
O
M
S
,
S
C
W
H
E
R
E
S
.
S
n
o
=
S
C
,
S
n
o
;
第二种写法
:
S
E
L
E
C
T
S
.
∗
,
S
C
.
∗
F
R
O
M
S
J
O
I
N
S
C
O
N
S
.
S
n
o
=
S
C
.
S
n
o
;
第一种写法: \\ SELECT S.*,SC.*\\ FROM\quad S, SC\\WHERE\quad S. Sno = SC, Sno;\\第二种写法:\\SELECT\quad S.*,SC.*\\FROM\quad S\quad JOIN\quad SC\quad ON\quad S. Sno = SC. Sno;
第一种写法:SELECTS.∗,SC.∗FROMS,SCWHERES.Sno=SC,Sno;第二种写法:SELECTS.∗,SC.∗FROMSJOINSCONS.Sno=SC.Sno;
eg:对前例使用自然连接完成
S
E
L
E
C
T
S
t
u
d
e
n
t
.
S
n
o
,
S
n
a
m
e
,
S
s
e
x
,
S
a
g
e
,
S
d
e
p
t
,
C
n
o
,
G
r
a
d
e
F
R
O
M
S
t
u
d
e
n
t
,
S
C
W
H
E
R
E
S
t
u
d
e
n
t
.
S
n
o
=
C
n
o
;
SELECT\quad Student.Sno,Sname,Ssex,Sage,Sdept,Cno,Grade\\FROM\quad Student,SC\\WHERE\quad Student.Sno=Cno;
SELECTStudent.Sno,Sname,Ssex,Sage,Sdept,Cno,GradeFROMStudent,SCWHEREStudent.Sno=Cno;
DBMS执行连接操作的基本过程是:
1.取S表中的第1个元组,在SC表中从头开始扫描,逐一检查每个元组是否满足连接条件
2.若是,则连接将其放到结果表,直到SC表全部查找完毕,再取S表中第2个元组。
3.重复以上过程,直到S表中的元组全部处理完毕。
由此可见,连接操作比较费时,如果在SC表的Sno列上建立排序或索引,这样只需对SC表扫描一遍,能够提高查询效率,这就是为什么要在经常查询的列或出现在连接条件的列上建立索引的原因。
在查询结果中没有取消掉重复的列,要想取消掉重复列,则在SELECT后的<目标列表达式>中指明。如果连接表中属性列名唯一,可以直接写出列名,否则要在列名前加上所属的表名。
连接查询不仅可以是两个表,也可以是两个以上的表进行连接。
3.3.2自身连接
自身连接:连接查询不仅是不同的表进行连接,还可以是一个表与其自己进行连接。(为了实现自身连接,要给两个表起两个别名,以此区分)
eg:查询每一门课的间接先修课
S
E
L
E
C
T
C
X
.
C
o
n
课程号
,
C
Y
.
C
p
n
o
间接先修课
F
R
O
M
C
C
x
,
C
C
y
W
H
E
R
E
C
X
.
C
p
n
o
=
C
Y
.
C
p
n
o
l
;
SELECT\quad CX.Con课程号,CY.Cpno间接先修课\\ FROM \quad C\quad Cx,C\quad Cy\\ WHERE\quad CX.Cpno=CY.Cpnol;
SELECTCX.Con课程号,CY.Cpno间接先修课FROMCCx,CCyWHERECX.Cpno=CY.Cpnol;
3.3.3外连接
在以上的连接查询中,不满足连接条件的元组不会在结果关系中出现。但有时用户希望这些元组出现在结果中。
外连接是利用关键字JOIN进行连接的。
外连接与普通连接区别:
1.普通连接操作只输出满足连接条件的元组;
2.外连接操作以指定表为连接主体,将主题表中不满足连接条件的元组一并输出。
外连接中最常用的是左外连接(列出左边关系中所有元组)和右外连接(列出右边关系中所有的元组)两种。
eg:查询所有学生的学号、姓名、选修的课程号及成绩。
S
E
L
E
C
T
S
.
S
n
o
,
S
n
a
m
e
,
C
n
o
,
G
r
a
d
e
F
R
O
M
S
L
E
E
T
O
U
T
E
R
J
O
I
N
S
C
O
N
S
,
S
n
o
=
S
C
.
S
n
o
;
SELECT\quad S. Sno, Sname, Cno, Grade\\ FROM\quad S\\ LEET\quad OUTER\quad JOIN\quad SC\\ ON\quad S, Sno = SC. Sno;
SELECTS.Sno,Sname,Cno,GradeFROMSLEETOUTERJOINSCONS,Sno=SC.Sno;
3.3.4复合条件连接
WHERE子句中含有多个连接条件
3.4嵌套语句
SQL允许多层嵌套。
查询块:一个SELECT-FROM-WHERE语句
嵌套查询:将一个查询块嵌套在另一个查询块的WHERE子句或HAVING短语的条件中的查询称。
嵌套查询过程:先求出内层查询(又称为子查询)的结果,再求外层查询(又称为父查询)的结果。
相关子查询:当子查询中查询条件依赖于外层查询中的某个值,而且子查询要反复求值用于外层查询使用。
子查询的限制:
1.不能使用ORDER BY子句
2.层层嵌套方式反映了SQL语言的结构化
3.有些嵌套查询可以用连接运算代替
当查询涉及多个表时使用嵌套查询逐次求解层次分明,反映了SQL具有结构化程序设计的特点,并且嵌套查询的执行效率比连接查询的笛卡儿积效率高。
在嵌套查询中,当用户能够确切地知道内层查询返回单值时,可以使用比较运算符(>,<,>=,<=,!=或<>等)。如果子查询的返回值不止一个,而是一个集合,一般使用IN谓词,也可以在比较运算符和子查询之间插入ANY或SOME(它们都表示任意一个,=ANY等价于IN)以及ALL(表示全部)。SQL允许<SOME,<=SOME,>=SOME, =SOME,和<>SOME的比较,也允许<ALL,<=ALL,>= ALL,=ALL,和<>ALL 的比较。
3.4.1带有IN谓词的子查询
eg:查询与‘王五’在同一个系的学生的学号、姓名、系名。
1.确定‘王五’所在系名
S
E
L
E
C
T
S
d
e
p
t
F
R
O
M
S
t
u
d
e
n
t
W
H
E
R
E
S
n
a
m
e
=
′
王
五
′
;
结果为:英语系
SELECT Sdept\\ FROM\quad Student\\ WHERE\quad Sname = '王五';\\ 结果为:英语系
SELECTSdeptFROMStudentWHERESname=′王五′;结果为:英语系
2.查找所有在英语系的学生
S
E
L
E
C
T
S
n
o
.
S
n
a
m
e
.
S
d
e
p
t
F
R
O
M
S
t
u
d
e
n
t
W
H
E
R
E
S
d
e
p
t
=
′
英语
系
′
;
SELECT\quad Sno.Sname.Sdept\\ FROM\quad Student\\ WHERE\quad Sdept = '英语系';
SELECTSno.Sname.SdeptFROMStudentWHERESdept=′英语系′;
或将第一步查询嵌入第二步查询的条件中
S
E
L
E
C
T
S
d
e
p
t
F
R
O
M
S
t
u
d
e
n
t
W
H
E
R
E
S
n
a
m
e
I
N
(
S
E
L
E
C
T
S
n
o
.
S
n
a
m
e
.
S
d
e
p
t
F
R
O
M
S
t
u
d
e
n
t
W
H
E
R
E
S
d
e
p
t
=
′
英语
系
′
)
;
SELECT Sdept\\ FROM\quad Student\\ WHERE\quad Sname\quad IN\\ \quad \quad \quad \quad \quad (SELECT\quad Sno.Sname.Sdept\\ \quad \quad \quad \quad \quad FROM\quad Student\\ \quad \quad \quad \quad \quad WHERE\quad Sdept = '英语系');
SELECTSdeptFROMStudentWHERESnameIN(SELECTSno.Sname.SdeptFROMStudentWHERESdept=′英语系′);
3.4.2带有比较运算符的子查询
当能确切的知道内层查询返回单值时,可用比较运算符(
》,
>
=
,
<
,
<
=
,
!
=
或
<
>
》,>=,<,<=,!=或<>
》,>=,<,<=,!=或<>)
与ANY或ALL谓词搭配使用
eg:一个学生只可能在一个系学习,并且必须属于一个系,则,在[前例]可以用=代替IN
S
E
L
E
C
T
S
n
o
,
S
n
a
m
e
,
S
d
e
p
t
F
R
O
M
S
t
u
d
e
n
t
W
H
E
R
E
S
d
e
p
t
=
(
S
E
L
E
C
T
S
d
e
p
t
F
R
O
M
S
t
u
d
e
n
t
W
H
E
R
E
S
n
a
m
e
=
′
小
b
′
)
;
SELECT\quad Sno,Sname,Sdept\\ FROM\quad Student\\ WHERE\quad Sdept = \\ \quad \quad \quad \quad \quad (SELECT\quad Sdept\\ \quad \quad \quad \quad \quad \quad FROM\quad Student\\\quad \quad \quad \quad \quad \quad WHERE\quad Sname = '小b');
SELECTSno,Sname,SdeptFROMStudentWHERESdept=(SELECTSdeptFROMStudentWHERESname=′小b′);
子查询一定要跟在比较运算符之后
相关子查询:子查询的相关条件依赖于父查询
不相关子查询:是一个独立的查询,其执行不依赖于外部查询。换句话说,不相关子查询可以在外部查询之前单独执行,并且其结果是固定的,不会因外部查询的不同行而改变。
3.4.3带有ANY(SOME)或ALL谓词的子查询
谓词语义:
ANY:任意一个值
ALL:所有值
eg:查询其他系中比计算机科学系某一学生年龄小的学生姓名和年龄
S
E
L
E
C
T
S
n
a
m
e
,
S
a
g
e
F
R
O
M
S
t
u
d
e
n
t
W
H
E
R
E
S
a
g
e
<
A
N
Y
(
S
E
L
E
C
T
S
a
g
e
F
R
O
M
S
t
u
d
e
n
t
W
H
E
R
E
S
d
e
p
t
=
′
计算机科学
系
′
)
;
SELECT\quad Sname,Sage\\ FROM\quad Student\\ WHERE \quad Sage<ANY(SELECT\quad Sage\\ \quad \quad \quad \quad \quad \quad \quad \quad\quad \quad\quad\quad FROM\quad Student\\\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad WHERE\quad Sdept='计算机科学系');
SELECTSname,SageFROMStudentWHERESage<ANY(SELECTSageFROMStudentWHERESdept=′计算机科学系′);
ANY Sdept<>‘计算机科学系’; /父查询块中的条件/
3.4.4带有EXIST谓词的子查询
1.EXIST谓词
带有EXIST谓词的子查询不返回任何数据,只产生逻辑真值“true”或逻辑假值“false”
若内层查询结果非空,则外层的WHERE子句返回真值
若内层查询结果为空,则外层的WHERE子句返回假值
2.NOT EXIST谓词
若内层查询结果非空,则外层的WHERE子句返回假值
若内层查询结果为空,则外层的WHERE子句返回真值
由EXIST引出的子查询,其目标列表达式通常都用*,因为带EXIST的子查询只返回真值或假值,给出列名无实际意义。
3.3.5集合查询
SELECT语句执行的结果是元组集合,当两个查询语句的结果结构完全相同即列数相同,相应的数据类型相同时,可以对这两个查询结构进行并(UNION),交(INTERSECT)和差(EXCEPT)操作。
集合操作的一般格式:
(
S
E
L
E
C
T
查询语句
1
)
U
N
I
O
N
[
A
L
L
]
∣
I
N
T
E
R
S
E
C
T
[
A
L
L
]
∣
E
X
P
E
C
T
T
[
A
L
L
]
(
S
E
L
E
C
T
查询语句
2
)
(SELECT 查询语句1)\\ UNION [ALL] \mid INTERSECT [ALL]\mid EXPECTT [ALL]\\ (SELECT 查询语句2)
(SELECT查询语句1)UNION[ALL]∣INTERSECT[ALL]∣EXPECTT[ALL](SELECT查询语句2)
用户根据需要选择三种聚合操作之一。
省略可选项ALL时,则表示返沪结果中取掉重复元组;若使用ALL,则表示返回结果中没有去掉重复元组。
3.3.6存储查询结果到表中
可以使用SELECT…INTO语句将查询结果存储到一个新建的数据表或临时表中。
eg:查询每位学生的学号及总分,将结果存储到一个新建的数据表Sno_Sum。
S
E
L
E
C
T
S
n
o
学号
,
S
U
M
(
G
r
a
d
e
)
总分
I
N
T
O
S
S
u
m
F
R
O
M
S
C
G
R
O
U
P
B
Y
S
n
o
;
SELECT\quad Sno学号,SUM(Grade)总分\\INTO\quad S\quad Sum\\ FROM\quad SC\\ GROUP\quad BY\quad Sno;
SELECTSno学号,SUM(Grade)总分INTOSSumFROMSCGROUPBYSno;
如果将INTOSSum改为INTO#SSum,则查询的结果被存放到一个临时表中,临时表只存储在内存中,并不存储在当前数据库中,所以其存在的时间非常短。
3.3.7基于派生表的查询
子查询不仅可以出现在WHERE子句中,还可以出现在FROM子句中,这时将子查询生成的临时派生表作为数据源。
eg:查询每位学生超过他自己选修课程平均分的课程号。
S
E
L
E
C
T
S
C
.
S
n
o
,
S
C
.
C
n
o
F
R
O
M
S
C
,
(
S
E
L
E
C
T
S
n
o
,
A
V
G
(
G
r
a
d
e
)
F
R
O
M
S
C
G
R
O
U
P
B
Y
S
n
o
)
A
S
S
A
V
G
(
S
n
o
,
G
r
a
d
e
A
V
G
)
W
H
E
R
E
S
C
,
S
n
o
=
S
_
A
V
G
.
S
n
o
A
N
D
S
C
,
G
r
a
d
e
>
S
_
A
V
G
,
G
r
a
d
e
_
A
V
G
;
SELECT\quad SC. Sno, SC. Cno\\FROM \quad SC,(SELECT\quad Sno, AVG(Grade) \quad FROM\quad SC\quad GROUP\quad BY\quad Sno )\\AS\quad S\quad AVG(Sno,Grade AVG)\\WHERE\quad SC,Sno = S\_AVG. Sno\quad AND\quad SC, Grade> S \_AVG,Grade\_AVG;
SELECTSC.Sno,SC.CnoFROMSC,(SELECTSno,AVG(Grade)FROMSCGROUPBYSno)ASSAVG(Sno,GradeAVG)WHERESC,Sno=S_AVG.SnoANDSC,Grade>S_AVG,Grade_AVG;
子查询(SELECT Sno,AVG(Grade)FROM SC GROUP BY Sno)生成一个派生表S_AVG(Sno,Grade_AVG),存储每位学生的学号和平均成绩。主查询将SC表与S_AVG进行连接查询,筛选出成绩大于其平均成绩的课程号。
3.5数据更新
SQL的数据更新包括插入数据、删除数据和修改数据等操作。
3.5.1插入数据
1.插入元组
将一行新元组插入指定表的语句格式为:
I
N
S
E
R
T
I
N
T
O
<
表名
>
[
(
<
列名
1
>
[
,
<
列名
2
>
…
)
]
V
A
L
U
E
S
(
<
值
1
>
[
,
<
值
2
>
]
…
)
INSERT\\INTO\quad <表名>[(<列名1>[,<列名2>…)]\\VALUES(<值1>[,<值 2>]…)
INSERTINTO<表名>[(<列名1>[,<列名2>…)]VALUES(<值1>[,<值2>]…)
其中,<列名>是可选项,省略时表示VALUES后的元组值列的顺序与基本表中的列名顺一致,并且对应列上的数据类型保持一致。若指定列名,则表示VALUES后的元组值只供给这些列名的值。
注意:VALUES子句中和各个数据之间必须用逗号分开,字符型数据和日期型数据要用单引号括起来;将VALUES子句中的值按照INTO子句中指定列名的顺序插人到表中,对于没有出现的列,将用NULL填充。
2.插入多个元组
将一个子查询的结果插入到指定表中。语句格式为:
I
N
S
E
R
T
I
N
T
O
<
表名
>
[
(
<
列名
1
>
[
,
<
列名
2
>
…
)
子查询
INSERT\\ INTO\quad <表名>[(<列名1>[,<列名2 >… )\\ 子查询
INSERTINTO<表名>[(<列名1>[,<列名2>…)子查询
eg:查询每位学生的平均成绩总分,将结果存储到一个新建的数据表AVGgrade。
先建立新表AVGgrade,用来存放每个学生的平均成绩。
C
R
E
A
T
E
T
A
B
L
E
A
V
C
g
r
a
d
e
(
S
n
o
C
H
A
R
(
8
)
,
A
V
G
G
R
S
M
A
L
L
I
N
T
)
CREATE\quad TABLE\quad AVCgrade(Sno\quad CHAR(8 ), AVGGR\quad SMALLINT)
CREATETABLEAVCgrade(SnoCHAR(8),AVGGRSMALLINT)
然后利用子查询求出每个学生的平均成绩,把结果存人新表AVGgrade中
I
N
S
E
R
T
I
N
T
O
A
V
G
g
r
a
d
e
S
E
L
E
C
T
S
n
o
,
A
V
G
(
G
r
a
d
e
)
总分
F
R
O
M
S
C
G
R
O
U
P
B
Y
S
n
o
;
INSERT\quad INTO\quad AVGgrade\\ SELECT\quad Sno,AVG(Grade)总分\\FROM\quad SC\\ GROUP\quad BY\quad Sno;
INSERTINTOAVGgradeSELECTSno,AVG(Grade)总分FROMSCGROUPBYSno;
3.5.2删除数据
使用DELETE语句删除指定表中的一行或多行元组。语句格式为:
D
E
L
E
T
E
F
R
O
M
<
表名
>
[
W
H
E
R
E
<
条件
>
]
DELETE\\FROM\quad <表名>\\ [WHERE<条件>]
DELETEFROM<表名>[WHERE<条件>]
可选项WHERE子句表示要删除满足条件的元组。省略时,则表示删除表中所有元组,但表的定义仍在数据字典中。
1.删除单个元组
eg:删除学生王小力的信息
D
E
L
E
T
E
F
R
O
M
S
W
H
E
R
E
S
n
a
m
e
=
′
王小
力
′
;
DELETE\quad FROM\quad S\\WHERE\quad Sname='王小力';
DELETEFROMSWHERESname=′王小力′;
2.删除多个元组
eg:删除所有学生的选课信息。
D
E
L
E
T
E
F
R
O
M
S
C
;
DELETE\quad FROM\quad SC;
DELETEFROMSC;
执行此语句后,SC成为一个空表,但其定义仍存在数据字典中。
3.利用子查询选择要删除的元组
eg:删除“数据库原理及应用”这门课的选课信息。
D
E
L
E
T
E
F
R
O
M
S
C
W
H
E
R
E
C
n
o
I
N
(
S
E
L
E
C
T
C
n
o
F
R
O
M
C
W
H
E
R
E
C
n
a
m
e
=
′
数拟库原理及启用’
)
;
DELETE\quad FROM\quad SC\\WHERE \quad Cno\quad IN\\ \quad\quad\quad (SELECT\quad Cno\\ \quad\quad \quad FROM\quad C\\ \quad \quad \quad WHERE\quad Cname='数拟库原理及启用’);
DELETEFROMSCWHERECnoIN(SELECTCnoFROMCWHERECname=′数拟库原理及启用’);
3.5.3修改数据
当用户需要修改关系中元组的某些值时,可以使用UPDATE实现。其语句格式为:
U
P
D
A
T
E
<
表名
>
S
E
T
<
列名
>
=
<
表达式
>
[
,
<
列名
>
=
<
表达式
>
]
.
.
.
W
H
E
R
E
<
条件
>
UPDATE\quad <表名>\\SET\quad <列名>=<表达式>[,<列名>=<表达式>]...\\WHERE\quad <条件>
UPDATE<表名>SET<列名>=<表达式>[,<列名>=<表达式>]...WHERE<条件>
该语句的功能是修改指定表中满足条件的元组中的指定属性值,其中,SET子句用于指定修改方法,即将<表达式>的值赋给相应的属性列。若省略WHERE子句,则表示要修改表中所有元组。
1.修改单个元组
eg:把学生田玲转到网络工程系。
U
P
D
A
T
E
S
S
E
T
S
d
e
p
t
=
′
网络工程
系
′
W
H
E
R
E
S
n
a
m
e
=
′
田
玲
′
;
;
UPDATE\quad S\\ SET\quad Sdept='网络工程系'\\WHERE\quad Sname='田玲';;
UPDATESSETSdept=′网络工程系′WHERESname=′田玲′;;
2.修改多个元组
eg:把选修了课程号为009的学生成绩提高5%
U
P
D
A
T
E
S
C
S
E
T
G
r
a
d
e
=
G
r
a
d
e
∗
(
1
+
0.05
)
W
H
E
R
E
C
n
o
=
′
00
9
′
;
UPDATE\quad SC\\SET\quad Grade = Grade * (1 + 0. 05)\\WHERE\quad Cno = '009';
UPDATESCSETGrade=Grade∗(1+0.05)WHERECno=′009′;
3.修改子查询选择要删除的元组
eg:把网络工程系的学生成绩提高10%
U
P
D
A
T
E
S
C
S
E
T
G
r
a
d
e
=
G
r
a
d
e
∗
1.1
W
H
E
R
E
′
网络工程
系
′
=
(
S
E
L
E
C
T
S
d
e
p
t
F
R
O
M
S
W
H
E
R
E
S
.
S
n
o
=
S
C
.
S
n
o
)
;
UPDATE\quad SC\\ SET\quad Grade = Grade * 1.1\\ WHERE '网络工程系'=\\ \quad \quad \quad( SELECT\quad Sdept\\ \quad\quad \quad FROM\quad S\\ \quad\quad \quad WHERE\quad S. Sno = SC. Sno);
UPDATESCSETGrade=Grade∗1.1WHERE′网络工程系′=(SELECTSdeptFROMSWHERES.Sno=SC.Sno);
子查询的作用是得到网络工程系的学生,这是一个相关子查询。
3.6视图
视图是一个虚表,它是从一个或几个基本表(或视图)导出的表,数据库中只存放视图的定义,而不存放视图对应的数据,当基本表中的数据发生变化,从视图中查询出的数据也随之改变。
3.6.1定义和删除视图
1.定义视图
定义视图语句格式为:
C
R
E
A
T
E
V
I
E
W
<
视图名
>
[
(
<
列名
>
[
,
<
列名
>
]
…
)
]
A
S
<
子查询
>
[
W
I
T
H
C
H
E
C
K
O
P
T
I
O
N
]
CREATE\quad VIEW\quad <视图名>[(<列名> [,<列名>]… )]\\AS\quad <子查询>\\ [WITH\quad CHECK\quad OPTION ]
CREATEVIEW<视图名>[(<列名>[,<列名>]…)]AS<子查询>[WITHCHECKOPTION]
说明:
(1)<列名>为可选项,省略时,组成视图的属性列名由子查询的结果决定。
(2)当视图由多个表连接得到,不同表中可能含有相同列以及视图列名为表达式或聚集函数的计算时,必须指定列名。
(3)子查询不允许含有 ORDER BY 子句和 DISTINCT 短语。
(4)带可选项WITHCHECKOPTION表示对视图进行更新操作时系统自动加上视图定义中的谓词条件。
带了可选项WITHCHECKOPTION,表示对视图进行更新操作时要满足视图定义中学生所在系名是“网络工程系”的约束。
2、删除视图
删除视图语句格式为:
D
R
O
P
V
I
E
W
<
视图名
>
DROP\quad VIEW<视图名>
DROPVIEW<视图名>
将视图定义从数据字典中删除
3.6.2查询视图
视图定义后、用户可以像基本表一样对视图进行査询(SELECT)操作。(视图名字出现FROM后)
eg:查询网络工程系2001年以后出生的学生学号和姓名。
S
E
L
E
C
T
S
n
o
,
S
n
a
m
e
F
R
O
M
N
E
_
S
W
H
E
R
E
Y
E
A
R
(
S
b
i
r
t
h
)
>
2001
;
SEL ECT\quad Sno, Sname\\FROM\quad NE\_S\\WHERE\quad YEAR(Sbirth)> 2001;
SELECTSno,SnameFROMNE_SWHEREYEAR(Sbirth)>2001;
执行过程是:首先系统从数据字典中找到NES定义,然后把该定义与用户的查询要求结合起来,转换成等价的对基本表S的查询,这一转换过程称为视图消解(VievResolution)
转换后的查询语句为:
S
E
L
E
C
T
S
n
o
,
S
n
a
m
e
F
R
O
M
S
W
H
E
R
E
S
d
e
p
t
=
′
网络工程
系
′
A
N
D
Y
E
A
R
(
S
b
i
r
t
h
)
>
2001
;
SELECT\quad Sno, Sname\\ FROM\quad S\\ WHERE\quad Sdept='网络工程系'\quad AND\quad YEAR(Sbirth)>2001;
SELECTSno,SnameFROMSWHERESdept=′网络工程系′ANDYEAR(Sbirth)>2001;
当对一个基本表进行复杂查询时,可以先定义一个视图,然后只需对该视图进行查询,这样将一个复杂的查询转换成一个简单的查询,从而简化用户的查询操作。
3.5.3更新视图
由于视图是一张虚表,所以对视图的更新最终要转换成对基本表的更新。视图的更新操作有插入、修改和删除操作,其语法格式与基本表的更新操作相同。
eg:在学生表S中插入一个学生信息(学号:20418010,姓名:李小丽,性别女,出生日期:2002-09-10,系别:网络工程系)。
I
N
S
E
R
T
I
N
T
O
N
E
_
S
V
A
L
U
E
S
(
2041801
0
′
,李小
丽
′
,
女
′
,
′
2002
−
09
−
1
0
′
)
;
INSERT\quad INTO\quad NE\_S\\ VALUES(20418010',李小丽',女','2002-09-10');
INSERTINTONE_SVALUES(20418010′,李小丽′,女′,′2002−09−10′);
执行过程是:首先系统从数据字典中找到NES定义,然后把该定义与插入操作结合起来,转换成等价的对基本表S的插入。
并不是所有视图中的数据都可以修改:若列是通过基本表计算得出的,在基本表没有对应的列,所以无法转换。(必须在基本表中有对应的列,才可以通过更新视图,更新基本表)
3.5.4 视图的作用
使用视图有以下几个优点:
(1)**视图能够简化用户操作。**为复杂的查询定义一个视图,用户不必输人复杂的查询渠视频语句,只需对该视图进行简单查询即可。
(2)**视图能够提供数据保密。**对不同用户定义不同的视图,使机密数据不出现在不,看到这些数据的用户视图中。例如,在学生表上定义了软件工程系视图,本系学生只能使用此视图,而无法访问其他系的学生数据。
(3)**视图能够保证数据的逻辑独立性。**数据的逻辑独立性是指当数据库的逻辑结构发生改变而保证应用程序不受影响。由于应用程序基于视图,当定义视图的基本表结构发生改变时,只需修改视图定义中的子查询部分,从而保证了视图不变,这样使用户的应用程序不受影响。
(4)**视图使用户能以多种角度看待同一数据。**数据库的特点之一是数据共享,当许多不同类型的用户在共享同一数据库时,视图使不同的用户以不同的方式看待同一数据。