第三章结构化查询语言--SQL
SQL(StructuredQueryLanguage)--结构化查询语言
3.1定义基本表和插入数据
3.1.1SQL数据库的体系结构
1.基本表(BaseTable):本身独立存在的表,即实际存储在数据库中的表而不是从项其它表导出来的。
2.视图(View):从一个或几个基本表或几个视图导出来的表。视图本身并不独立存储数据,系统只保存视图的定义。
SQL支持的数据库体系结构--存储模式(内模式)、模式、外模式。
从用户的观点出发,基本表和视图都是关系,SQL一样访问它们。基本表对应"模式",视图对应"外模式"。
3.1.2定义基本表
定义基本表就是创建一个基本表,对表名(关系名称)以及它所包括的各个属性名及其数据类型作出具体规定。
命令格式:
CREATETABLE表名(字段名1类型(宽度,小数),字段名2类型(宽度,小数),┄┄)
命令功能:用于建立一个基本表。
例:CARTETABLE图书(总编号C(6),分类号C(8),书名C(16),作者C(6),单价N(10,2))
3.1.3修改、删除基本表
ALTERTABLE图书ADD(作者C(8),出版单位C(20))
在"图书"数据库结构中增加"作者"和"出版单位"两个字段。
DROPTABLE<基本表名>删除基本表的命令
3.1.4插入数据
命令格式:
INSERTINTO表名[(字段名1,字段名2)┄┄]VALUES(表达式1,表达式2┄┄)
命令功能:按给定的字段值在数据库的末尾追加一条新记录。
例:INSERTINTO图书VALUES("446943","TP31/138","数据库基础","杨华",17.8)
INSTERINTO图书(书名,作者,单价)VALUES("FoxPro大全","周虹",28.6)
3.2SQL查询--SQL-SELECT
SQL的查询可以很方便地从一个或多个表中检索数据,查询是高度非过程化的,用户只需要明确提出"要干什么",而不需要指出"怎么去干"。
SQL基本查询模块的结构:
SELECT<表达式1>,<表达式2>┄<表达式n>;--查询目标(对所需的属性进行投影运算)
FROM<关系1>,<关系2>,┄<关系m>;--查询的源(所有关系的关系名)
WHERE<条件表达式>--查询目标必须满足的条件(选择运算)
有关选择运算(条件表达式)需要用到的运算符:
1.比较运算符:P49
2.逻辑运算符:AND逻辑与、OR逻辑或、NOT逻辑非。
3.谓词:ALL所有、ANY任意、BETWEEN。。。AND。。。之间、IN包含、NOTIN不包含、EXISTS存在、NOTEXISTS不存在。
4.集合运算:UNION集合的并、INTERSECT集合的交、MINUS集合的差。
图书管理关系数据模型包括的三个基本表(数据库文件):
图书(总编号,分类号,书名,作者,出版单位,单价)
读者(借书证号,单位,,性别,职称,地址)
借阅(借书证号,总编号,借书日期)
(包含的记录P50页)
3.2.1简单查询
例:找出姓李的读者及其所在单位。
SELECT,单位;
FROM读者;
WHERE="李"
例:SELECT*;
FROM读者
1.DISTINCT和ALL子句
DISTINCT子句的作用:从查询结果中去掉重复元组。
ALL子句:不去掉重复元组(是默认值)
例:SELECTDIST书名,出版单位;
FROM图书
2.用AS指定查询结果的自定义列名
例:SELECT书名ASBook,作者ASAuthor,出版单位ASPublisher;
FROM图书;
WHERE出版单位="科学出版社"
3.ORDERBY子句
ORDERBY子句可以指出对查询结果排序。用字段名或查询结果的列序号指定排序关键字。DESC表示降序,ASC表示升序。系统默认为升序。允许多重排序。
例:SELECT书名,出版单位,单价;
FROM图书;
WHERE出版单位="高等教育出版社";
ORDERBY单价DESC
4.BETWEEN。。。AND。。。和NOTBETWEEN。。。AND。。。(谓词,在WHERE子句中使用)
例:SELECTDIST书名,作者,出版单位,单价;
FROM图书;
WHERE单价BETWEEN10AND20;(单价>=10AND单价<=20)
ORDERBY出版单位,单价DESC
5.谓词IN
在WHERE子句中,条件可以用IN表示包含在其后面括号指定的集合中。括号中的元素可以直接列出,也可以是一个子查询模块的查询结果。
例:SELECTDIST书名,作者,出版单位;
FROM图书;
WHERE出版单位IN("高等教育出版社","科学出版社")
等价语句:WHERE出版单位="高等教育出版社"OR出版单位="科学出版社"
6.LIKE及通配符"-"和"%"
下划线-代表任意一个字符,百分号%代表任意多个(包括零个)任意字符。
例:SELECTDIST书名,作者;
FROM图书;
WHERE书名LIKE"计算机%"(计算机基础,计算机网络)
例:SELECTDIST书名,作者;
FROM图书;
WHERE书名LIKE"%基础%"(计算机基础,数据库基础教程)
7.为关系指定临时别名
有些查询涉及到同一个数据库文件检索两次,或者是多个数据库查询,就有必要引入别名。用户可以自定义临时别名,在FROM子句中直接给出,并在SELECT和WHERE子句中用别名对字段加以限制。
例:查询同时借阅了总编号为"112266"和"449901"两本书的借书证号。
SELECT借书证号;
FROM借阅;
WHERE总编号="112266"AND总编号="449901"
以上语句的查询结果为空,因为不可能存在一个其总编号既是"449901"又是"112266"的借阅记录。所以此地需要用到表的临时别名。
SELECTX.借书证号,X.总编号ASFirst,Y.总编号ASSecond;
FROM借阅X,借阅Y;
WHEREX.借书证号=Y.借书证号;
ANDX.总编号="112266";
ANDY.总编号="449901"
这里把"借阅"引用了两次,一个别名为X,另一个为Y,这样相当于是从两个数据库中进行查询。
3.2.2联接查询
当查询目标涉及到两个或几个关系时,要进行联接运算。这时只要在FROM子句中指出各个关系的名称,在WHERE子句里正确指出联接条件即可。
如果不同关系中具有相同的属性名,为避免混淆必须在前面冠以别名用圆点分开,如果没有起别名则可用原名。
例:查找所有借阅了图书的读者的和单位。
SELECTDIST,单位;
FROM读者,借阅;
WHERE读者.借书证号=借阅.借书证号
SELECT子句中的输出列--如果在SELECT子句中加入了字符串常量,则在每个查询输出的元组中都会输出这个字符串。
例如:找出李某所借的所有图书的书名及借书日期。
SELECT,"所借图书",书名,借书日期;
FROM图书X,借阅Y,读者Z;
WHEREY.借书证号=Z.借书证号;
ANDX.总编号=Y.总编号AND="李"
例如:查找价格在22元以上已借出的图书,结果按单价升序排列。
SELECT*;&;&;*号代表图书和借阅两个关系联接后的所有属性。
FROM借阅,图书;
WHERE图书.总编号=借阅.总编号AND单价>=22;
ORDERBY单价
注:在查询输出中,系统对两个数据库中相同的字段(总编号)自动加上-A和-B。
3.2.3嵌套查询
嵌套查询是指在SELECT-FROM-WHERE查询块内部再嵌入另一个查询块(子查询)。注意,ORDERBY子句不能出现在子查询中。
1.用一个子查询模块的查询结果作为IN包含的列表。
如上例可用下列语句代替:(查找价格在22元以上已借出的图书)
SELECT*;
FROM借阅;
WHERE总编号IN;
(SELECT总编号;
FROM图书;
WHERE单价>=22)
例:查询1997年7月以后没有借书的读者的借书证号、和单位。
SELECT借书证号,,单位;
FROM读者;
WHERE借书证号NOTIN;
(SELECT借书证号;
FROM借阅;
WHERE借书日期>={07/01/97})
2.ALL和ANY和SOME
在WHERE子句中,ALL表示与子查询结果中所有记录的相应值相比较均符合要求才算满足条件,而ANY或SOME表示与子查询结果相比较,任何一个记录满足条件即可。
例如:找出藏书中比高等教育出版社的所有图书单价更高的书籍。
SELEC和*;
FROM图书;
WHERE单价>ALL;
(SELECT单价;
FROM图书;
WHERE出版单位="高等教育出版社")
例:找出藏书中所有与"数据库导论"或"数据库基础"在同一出版单位出版的书。
SELECTDIST书名,单价,作者,出版单位;
FROM图书;
WHERE出版单位=ANY;
(SELECT出版单位;
FROM图书;
WHERE书名IN("数据库导论","数据库基础"))
3.2.4使用库函数(统计函数)查询
计数函数COUNT(<字段名>)统计字段名所在列的行数。
一般用COUNT(*)表示计算查询结果的行,即元组的个数。
求和函数SUM(<字段名>)对某一列的值求和(必须是数值型字段)
计算平均值AVG(<字段名>)对某一列的值计算平均值(必须是数值型字段)
求最大值MAX(<字段名>)找出一列中的最大值
求最小值MIN(<字段名>)找出一列中的最小值
注意:在使用库函数查询时,选用AS指定列名显得特别有用。
例:求图书馆所有藏书的总册数。
SELECTCOUNT(*)AS藏书总册数;
FROM图书
例:求科学出版社出版的图书的最高价格、最低价格、平均价格。
SELECT出版单位,MAX(单价)AS最高价,MIX(单价)AS最低价;
AVG(单价)AS平均价;
FROM图书;
WHERE出版单位="科学出版社"
例:求信息系当前借阅图书的读者人次。
SELECT"信息系",COUNT(借书证号)AS借书人次;
FROM借阅;
WHERE借书证号IN;
(SELECT借书证号;
FROM读者;
WHERE单位="信息系")
结果:EXP-1借书人次
信息系3
*分组合计GROUPBY子句
GROUPBY子句的作用是按指定项目对记录分组,然后对每一组分别使用库函数。
通常分组项目为字段,该字段应出现在查询结果中,否则分不清统计结果属于哪一组。
例如:求出各出版社出版的图书的最高价、最低价和册数。
SELECT出版单位,MAX(单价)AS最高价,MIX(单价)AS最低价;
COUNT(*)AS总册数;
FROM图书;
GROUPBY出版单位
注:本例中如果没有GROUPBY子句,则统计结果是整个图书表的数据,有了"GROUPBY出版单位"子句后,则可以求出各出版单位的数据。
例:求出各单位当前借阅图书的人次。
SELECT单位COUNT(*)AS借阅人次;
FROM读者,借阅;
WHERE读者.借书证号=借阅.借书证号;
GROUPBY读者.单位
*HAVING子句
HAVING子句一般跟在GROUPBY子句之后,其作用是限定分组检索条件,条件中一般都包含库函数。(在WHERE子句里不能直接用库函数作为条件表达式)
例:分别找出借书人次超1人的单位及人次数。(比上例增加一个HAVING子句)
SELECT单位,COUNT(*)AS超过1人次;
FROM借阅,读者;
WHERE读者.借书证号=借阅.借书证号;
GROUPBY读者.单位;
HAVINGCOUNT(*)>=2
*存在量词EXISTS和NOTESISTS
在嵌套查询时,主查询的WHERE子句的条件中可以用EXISTS表示存在。如果子查询结果非空,则满足条件;NOTEXISTS正好相反,表示不存在,如果子查询结果为空,则满足条件。
例如:查询经济系是否还清所有借书。如果还清,显示该系所有读者的、所在单位和职称。
SELECT,单位,职称;
FROM读者;
WHERE单位="经济系"ANDNOTEXISTS;
(SELECT*;
FROM借阅,读者;
WHERE读者.借书证号=借阅.借书证号AND单位="经济系")
注:如果子查询不为空,说明该系还未还清全部借书,则条件不成立,不显示该系读者的、所在单位和职称。如果子查询为空,说明所借的书已全部还清,则显示该系读者的、所在单位和职称。
3.3部份SQL数据操纵命令
*更新数据命令--修改数据
命令格式:UPDATE<表名>;
SET<更新表达式>;
[WHERE<条件>]
例:修改总编号为554433图书的作者名和出版单位名称。
UPDATE图书;
SET作者="王为民",出版单位="电子工业出版社";
WHERE总编号="554433"
*删除数据命令
命令格式:DELETE;
FROM<表名>;
WHERE<条件>
例如:借书证号"112"所借总编号为"446988"的图书已归还,删除该借阅记录。
DELETE;
FROM借阅;
WHERE借书证号="112"AND总编号="446988"
《数据库基础与应用》第三章结构化查询语言--SQL第1页共6页