Access Access 数数数数数数数数 数数数数数数数数 数数数数数数数数数 数数数数数数数数数 数数数数 数数 数数数数 数数
Access Access 数据库与程序设计数据库与程序设计
四川大学计算机学院四川大学计算机学院主讲教师 曾新主讲教师 曾新
第 5章 结构化查询语言 SQL SQL 语言简介 SQL 语言的数据定义功能
建立表结构、修改表结构、删除数据表 SQL 语言的数据操纵功能
记录的插入、记录的删除、记录的更新 SQL 语言的查询功能
简单查询 条件查询 连接查询 嵌套查询 统计查询 分组查询 查询排序 合并查询 查询的输出
第 5章 结构化查询语言 SQL
结构化查询语言 SQL ( Structured Query Language ),是关系数据库的标准语言,它具有数据定义、数据操纵、数据查询和数据控制等功能,并且其语言简洁、功能强大,目前广泛用于各大、中、小型关系数据库,已成为世界上最流行的数据库语言之一。
结构化查询语言 SQL
SQL 语言的产生和发展 1974 年由 Boyce 和 Chamberlin 提出,并作为 IBM 公司研制的关
系数据库管理系统原型 SYSTEM R 的查询语言文本。 1982 年, ANSI (美国国家标准局)成立 SQL 标准委员会。 1986 年 10 月, ANSI SQL 标准被批准作为关系数据库语言的美国
标准。公布了 SQL 标准文本( SQL-86 )。 1987 年 6月, ISO (国际标准化组织)将其采纳为国际标准。 SQL-89 、 SQL92 和 SQL99 等。 目前 SQL 已被许多 DBMS 产品如, DB2 、 INGRES 、 SYSBASE 、 SQL
Server 、 VFP 和 ORACLE 等所采用,它已成为关系数据库领域中一个主流语言。
结构化查询语言 SQL SQL 语言的特点 一体化
将所有的对数据库的定义、查询、更新、控制、维护、恢复、安全等一系列操作要求统一为一种语言。
非过程化 交互式 SQL 是一种自含式语言,可独立使用,用于一
般用户建立中、小型管理信息系统 嵌入式 SQL 是将 SQL 语言嵌入到高级语言中,用户可
利用高级语言灵活地表达计算功能和 SQL 数据处理功能,以便完成各种复杂的事务处理。
结构化查询语言 SQL
简洁化 SQL 语言功能强大并且只用几条命令来完成,其
语法也非常简单,很接近自然语言模式。 SQL的命令有:数据查询命令( SELECT )、数据定义命令( CREATE 、 DROP 、 ALTER )、数据操纵命令( INSERT 、 UPDATE 、 DELETE )和数据控制命令( GRANT 、 REVOKE )。
5.2 SQL 语言的数据定义功能 打开数据库。 在“设计视图” 新建查询,在弹出的“显示表”对话框中直接点击“关闭”。
• “ 查询”-“ SQL 特定查询” - “ 数据定义查询”
5.2 SQL 语言的数据定义功能
建立数据表结构
定义数据表的结构。 CREATE TABLE < 表名 > (< 字段名 1> < 数据类型 1> [(< 大小 >)] [NOT NULL] [PRIMARY KEY | UNIQUE|REFERENCES 外部表 [( 外部关键字 )]] [ , < 字段名 2> < 数据类型 2> [(< 大小 >)] [NOT NULL] [PRIMARY KEY | UNIQUE|REFERENCES 外部表 [( 外部关键字 )]] [ , ...]])
SQL- 建立表结构
建立一个“学生名册”表结构( CREATE TABLE 命令) CREATE TABLE 学生名册 ( 学号 TEXT(10) PRIMARY KEY, 姓名 TEXT(8), 性别 TEXT(2), 出生日期 DATE, 院系 TEXT(12), 总分 INTEGER, 奖学金
LOGICAL, 简历 MEMO, 照片 OLEOBJECT)
•选择“数据定义查询”类型•写入 SQL 语句•运行查询
使用 SQL创建的表结构
使用 SQL创建的表结构
CREATE TABLE 课程表 ( 课程号 TEXT(6) PRIMARY KEY, 课程名 TEXT(20), 开课院系 TEXT(12), 学分 INTEGER, 学时 TEXT(2) )
SQL- 建立表结构 建立“成绩表” ,并与“学生名册”建立关
系 CREATE TABLE 成绩 ( 学号 TEXT(10) REFERENCES 学生名册 (学号 ), 课程号 TEXT(6), 课序号 TEXT(2), 成绩 INTEGER)
2 、修改基本表 增加字段 ALTER TABLE 表名 ADD 字段名 数据类型 修改字段 ALTER TABLE 表名 ALTER 字段名 数据类型 删除字段 ALTER TABLE 表名 DROP 字段名
SQL- 修改表结构
SQL- 修改表结构
例:为“学生名册”增加字段一个“电子邮件”字段
ALTER TABLE 学生名册
ADD 电子邮件 TEXT(20)
增加字段 SQL 查询增加字段 SQL 查询
5.3 SQL 语言的数据操纵功能 1 . SQL- 插入数据 INSERT INTO 表名 (列名 1,列名 2……) VALUES ( 表达式 1,表达式 2……)
【例】向“学生情况”表中插入一个新的学生记录
INSERT INTO 学生情况 2VALUES ("112", " 王汉 ", " 男 ", #10/21/1980#, "586", TRUE, " 足球 ", "1")
5.3 SQL 语言的数据操纵功能 【例】 使用 SQL 命令向“课程”表中追加插入一条包
含部分信息的新记录。 INSERT INTO 课程 ( 课程号 ,课程名称 ,学分 ) VALUES("201003","CAD 设计 ",2) 如果仅为表中的部分字段赋值,应注意字段名称与
字段值要一一对应。
5.3 SQL 语言的数据操纵功能 2 . SQL- 修改数据 UPDATE 表名 SET 列名 1 =表达式 1 ,列名 2 =表达式 2
…… WHERE 条件 UPDATE 学生情况 2 SET 性别=“女” WHERE 姓名=“王汉”
数据操纵 3 . SQL- 删除数据 DELETE FROM 表名 WHERE 条件
5.4 SQL 语言的查询功能
SELECT [ALL|DISTINCT] [ 表别名 .] 字段名 [AS 列名 ],…. FROM [ 数据库名 !] 表名 [WHERE 条件 ] [GROUP BY 分组名 ] [HAVING 条件 ] [UNION[ALL]SELECT 语句 ] [ORDER BY 排序项 ]
分组中的条件
【命令】 SELECT [ALL | DISTINCT] [TOP < 数值表达式 > [PERCENT]] < 目标列选项 > [AS < 列标题名 >][ INTO < 新表名 >] FROM < 表名 1> [[AS] < 别名 1>],< 表名 2> [[AS] < 别名 2>] [WHERE < 连接条件 1> [AND < 连接条件 2> ...] [AND | OR < 过滤条件 1> [AND | OR < 过滤条件 2> ...]]] [GROUP BY < 分组列名 1> [, < 分组列名 2> ...]] [HAVING < 过滤条件 >] [UNION [ALL] <SELECT 命令 >] [ORDER BY < 排序项 1>[ASC | DESC] [, < 排序项 2> [ASC | DES
C] ...]]
查询实例 相关表:
学生信息表 学生成绩表 课程信息表
单表查询 例 1 :例出全部学生信息 SELECT * FROM 学生信息表 “*”– 全部数据
SELECT-SQL 简单查询
【例 5-11 】查询“学生信息表”中所有学生的姓名、性别、出生日期。
SELECT 姓名 AS 学生姓名 , 性别 , 出生日期 AS 生日 FROM 学生信息表
SELECT-SQL 简单查询
单表查询 例 2 :例出所有女生的学号及姓名 SELECT 学号 , 姓名 FROM 学生信息表 WHERE 性别 =“ 女”
单表查询 例 3:例出所有学生的性别 SELECT DISTINCT 性别 FROM 学生信息表 * 列出性别为“男”的学生 SELECT 姓名,性别 FROM 学生情况 WHERE 性别 =“ 男”
SELECT-SQL 简单查询
单表查询 例 4:例出课程号为” 303001” 且成绩大于 80 分的学生学号
及成绩,并按成绩由高到低排序。 SELECT 学号,成绩 FROM 学生成绩表 WHERE 课号 =“303001” AND 成绩 >=80 ORDER BY 成绩 DESC
SELECT-SQL 简单查询
SELECT-SQL 简单查询
单表查询 例 5 :查询 84 年以后出生的学生。 SELECT 姓名,出生日期 FROM 学生信息表 WHERE 出生日期 >=#1984-01-01#
注意日期的写法
SELECT-SQL 简单查询
单表查询 例 6 :查询不是“艺术学院”的学生。 SELECT 姓名,院系名称 FROM 学生信息表 WHERE 院系名称 <>“艺术学院” 院系名称 !=“艺术学院”
【例 5-13】查询“学生信息表”中所有艺术学院和软件学院学生的学号、姓名和所在院系名称。
SELECT 学号 , 姓名 , 院系名称 FROM 学生信息表 WHERE 院系名称 IN (”艺术学院” ,”软件学
院” )
WHERE 院系名称 =”软件学院” OR 院系名称 =”艺术学院”
WHERE 院系名称 NOT IN (”艺术学院” ,”软件学院” )
SELECT-SQL 简单查询 单表查询 例 7:查询成绩在 70 到 80之间的学生选课得分情况。 SELECT * FROM 学生成绩表 WHERE 成绩 BETWEEN 70 AND 80
WHERE 成绩 >=70 AND 成绩 <=80 WHERE 成绩 NOT BETWEEN 70 AND 80 WHERE 成绩 <70 or 成绩 >80
WHERE 成绩 BETWEEN 70 AND 80
WHERE 成绩 NOT BETWEEN 70 AND 80
SELECT-SQL 简单查询 例 9 :列出所有姓“张”的学生的情况。 SELECT * FROM 学生信息表 WHERE 姓名 LIKE “张 ??“
LIKE “张 ??", “?”代表任意一个字符 LIKE “张 *", “*”代表任意多个字符 WHERE 姓名 NOT LIKE “张 ??"
SELECT-SQL 统计查询
AVG -----按列求平均 SUM -----按列求和 COUNT -----按列统计个数 MAX ----- 求一列中的最大值 MIN ----- 求一列中的最小值
统计入学总分大于 600 分的男生有多少人 SELECT COUNT ( 姓名 ) from 学生信息表
WHERE 入学总分 >=600 AND 性别 =' 男 ' SELECT COUNT ( 姓名 ) AS 合格人数 from
学生信息表 WHERE 入学总分 >=600 AND 性别 =' 男 '
SELECT-SQL 统计查询
例 10 :求全体学生的入校总分、最高分、最低分和平均分
SELECT SUM( 入学总分 ) AS 新生入校总分 , MAX( 入学总分 ) AS 新生最高分 , MIN( 入学总分 ) AS 新生最低分 ,
AVG( 入学总分 ) AS 新生平均分 FROM 学生信息表
SELECT-SQL 统计查询
例 11:求入校总分在 580 分以上的学生人数
SELECT COUNT(*) AS 总分大于 580的人数 FROM 学生信息表 WHERE 入学总分 > 580
SELECT-SQL 统计查询
例 13:查出学生成绩表中选修“ 101002”课程的最高分、最低分和相差分数
SELECT MAX( 成绩 ) AS 最高分 , MIN( 成绩 ) AS 最低分 , MAX( 成绩 )- MIN( 成绩 ) AS 相差分数 FROM 学生成绩表 WHERE 学生成绩表 .课程号 = "101002";
SELECT-SQL 连接查询 例 14. 查询成绩在 90 分以上的学生记录,并显示该生的学号、姓
名、课程号和成绩相关表:学生情况、选课表 Where 连接 : 只连接相等的记录 连接条件: WHERE 学生信息表 .学号 =学生成绩表 .学号 AND 成绩 >=90 SELECT 学生信息表 .学号 ,学生信息表 .姓名 ,学生成绩表 .课程号 ,学生成绩表 .成绩 from 学生信息表 , 学生成绩表 where 学生信息表 .学号 =学生成绩表 .学号 AND 成绩 >=90
SELECT a. 学号 , 姓名 , 课程号 , 成绩 from 学生信息表 a, 学生成绩表 b where a. 学号 =b. 学号 AND 成绩 >=90
临时定义别名
INNER JOIN 连接 SELECT 学生信息表 2.姓名 , 学生成绩表 2.成绩 FROM 学生信息表 2 INNER JOIN 学生成绩表 2 ON 学生信息表 2.
学号 = 学生成绩表 2.学号 WHERE ((( 学生成绩表 2.成绩 )>=90));
SELECT 学生信息表 2.姓名 , 学生成绩表 2.成绩FROM 学生信息表 2 LEFT JOIN 学生成绩表 2 ON 学生信息表 2.学号 = 学生成绩表 2.学号WHERE ((( 学生成绩表 2.成绩 )>=90));
LEFT JOIN 连接
RIGHT JOIN 连接SELECT 学生信息表 2. 姓名 , 学生成绩表 2. 成绩FROM 学生信息表 2 RIGHT JOIN 学生成绩表 2 ON 学生信息表 2. 学号 = 学生成绩表 2. 学号WHERE ((( 学生成绩表 2. 成绩 )>=90));
SELECT-SQL 连接查询 例 15. 列出选修 1 号课的学生姓名及成绩。
相关表:学生情况 选课表
连接条件: WHERE 学生名册 . 学号 =选课表 . 学号 AND 课号 =“1” SELECT * FROM 学生情况 AS S, 选课表 AS C WHERE S. 学号 =C. 学号 AND 课号 ="1";
临时定义表的别名 S 和 C 可以减少书写长的表名
分组查询 :GROUP BY
例 18. 列出各门课的平均成绩、最高成绩、最低成绩和选课人数。
SELECT 学生成绩表 2.课程号 , Avg( 学生成绩表 2.成绩 ) AS 成绩之平均值 , Max( 学生成绩表 2.成绩 ) AS 成绩之最大值 , Min( 学生成绩表 2.成绩 ) AS 成绩之最小值 , Count( 学生成绩表 2.学号 ) AS 学号之计数
FROM 学生成绩表 2 GROUP BY 学生成绩表 2.课程号 ;
SELECT 学生成绩表 2.课程号 , ROUND(Avg( 学生成绩表 2.成绩 ),2) AS 平均分 , Max( 学生成绩表 2.成绩 ) AS 最高分 , Min( 学生成绩表 2.成绩 ) AS 最低分 , Count( 学生成绩表 2.学号 ) AS 选课计数
FROM 学生成绩表 2 GROUP BY 学生成绩表 2.课程号 ;
ROUND(X,N) :N给出小数位数
HAVING 子句 ( 函数 ) HAVING函数与 GROUP BY子句联合使用 ,可以对分组后
的结果作进一步的限制 . 例 18a. 列出选课人数超过 3 人的各门课的平均成绩、最高成绩、最低成绩和选课人数。
SELECT 学生成绩表 2. 课程号 , Round(Avg( 学生成绩表 2. 成绩 ),2) AS 平均分 , Max( 学生成绩表 2. 成绩 ) AS 最高分 , Min( 学生成绩表 2. 成绩 ) AS 最低分 , Count( 学生成绩表 2. 学号 ) AS 选课计数
FROM 学生成绩表 2 GROUP BY 学生成绩表 2. 课程号 HAVING Count( 学生成绩表 2. 学号 )>3
计算: SELECT 学生信息表 2. 姓名 , 学生信息表 2. 性别 , Year(Date())-Year( 学生信息表 2!出生日期 ) AS 年龄
FROM 学生信息表 2;WHERE Year(Date())-Year( 学生信息表 2!出生日期 )=20
SQL 嵌套查询 一个 SELECT-FROM-WHERE 语句中嵌套进另外一个 SEL
ECT-FROM-WHERE 称为嵌套查询。上层查询称为外层查询或父查询,下层查询被称为内层查询或子查询。
子查询中不能使用 ORDER BY 语句,因为该语句是对最终结果进行排序。
嵌套查询的运行方式是由里向外,也就是说,每个子查询都先于它的父查询执行,而子查询的结果作为其父查询的条件。
嵌套查询如果查询所要求的结果出自一个关系,而相关的条件却涉及多
个关系,则可以利用嵌套查询来完成。 嵌套查询一般有 2 种形式: < 表达式 > <比较运算符 > [ANY|ALL|SOME] (<子查询
>) [NOT] EXISTS (<子查询 >) 说明:( 1 )其中比较运算符可以为 [NOT]IN/[NOT]BETWEEN…
AND…/[NOT]LIKE( 2 ) ANY和 SOME是同义词,在进行比较运算时,只要子查
询中有一条为真,则结果为真;而 ALL则要求子查询中全部记录都为真,结果才为真。
( 3 ) EXISTS是谓词,检查子查询中是否有结果返回。
【例】查询哪些专业至少有一学生成绩等于 100 分 SELECT DISTINCT 专业代号 FROM 学生 WHERE 学生 . 学号 IN ( SELECT 学号 FROM 成绩表 WHERE 成绩表 . 成绩 =100 )
注意: (1)这里所要查询的结果是“学生表”的专业信息,而相关的条件却是
“成绩表”的成绩字段的值,因此使用嵌套查询; (2) “SELECT 学号 FROM 成绩表 WHERE 成绩表 . 成绩
=100 ) ”是子查询,且用括号包含。 学号: 10002 专业代号: 10234 10005 10567
学号: 10002 成绩: 100 10005 100
先找出成绩为 100 的学号,再找出这些学号所对应的专业代码
【例】查询与“张三”专业相同的学生姓名 SELECT 姓名 FROM 学生 ; WHERE 学生 .专业代码= (SELECT 专业代码 FROM 学生 WHERE 姓名 in (“张三” ))
【例】在成绩表中检索选修 2 号课程的学生中比选修 4 号课程的最低分数要高的学生学号和成绩。
SELECT 学号 , 成绩 FROM 成绩 ; WHERE 课程代号 =”2” AND 成绩 >ANY ; (SELECT 成绩 FROM 成绩 WHERE 课程代号 =”4”)
【例】在成绩表中检索选修 2 号课程的学生中成绩比选修 4 号课程的所有学生成绩都要高的学生学号和成绩。
SELECT 学号 , 成绩 FROM 成绩 WHERE 课程代号 =”2” AND 成绩 > ALL ;
(SELECT 成绩 FROM 成绩 WHERE 课程代号 =”4”)
any 表示任意一个, all 表示所有的。 如果有张学生记录表 student 中有一个属性组为 age 现在要查找年龄在某个区间上的学生记录就有如下操作
1 、查找年龄比 15 、 16 、 22 、 21 、 17 、 18 、 19 中任意一个都小的学生记录就有如下代码:
select * from student where age<any(15,16,22,21,17,18,19)
2 、查找年龄比 15 、 16 、 22 、 21 、 17 、 18 、 19 中任意一个都大的学生记录就有如下代码:
select * from student where age>any(15,16,22,21,17,18,19) 这里用 any 和 all 是等效的 用 all 是大于所有的意思 用 all 就改为: where age>all ( 15,16,22,21,17,18,19 ) 这里 <any 就是 in ame 小于括号内部那个子查询所的结果中的
任意一个值,也就是说小于其中最小的一个。
SQL 嵌套查询
列出临床医学专业所有的必修课设置情况 相关表:课程表,必修课 首先在必修课表中找出临床医学专业所必修的课号, 再在课程表中选出属于那个课号的记录
SELECT-SQL 嵌套查询
SELECT * FROM 课程表 WHERE 课号 IN (SELECT 课号 FROM 必修课 WHERE 必修专业 ="临床医学 ")
SQL嵌套查询
例: 列出最少选修了三门课的学生姓名。 SELECT 姓名 FROM 学生情况 WHERE 学号 IN (SELECT 学号 FROM 选课表 GROUP BY 学号 HAVING COUNT(*)>=3)
在分组中统计满足条件,此处不能用Where
在分组中统计满足条件,此处不能用Where
例:查询所有选修了 2 号课程的学生姓名 SELECT 姓名 FROM 学生信息表 WHERE EXISTS (SELECT * FROM 学生成绩表 cj,学生信息表 st WHERE cj. 学号= st. 学号 AND 课程号=” 2”)
EXISTS 的意思是存在,带有 EXISTS谓词的子查询不返回数据,只产生逻辑真“ TRUE”或逻辑假“ FALSE”.EXISTS 的意思是存在,带有 EXISTS谓词的子查询不返回数据,只产生逻辑真“ TRUE”或逻辑假“ FALSE”.