- SQL 语言概述
- SQL 语言提出和发展
- SQL 语言的功能概述
- 利用 SQL 语言建立数据库
- 学生选课数据库 SCT
- 1. 定义数据库和表 SQL-DDL
- 创建数据库的语句—Create Database
- 创建关系/表的语句—Create Table
- 2. 向表中追加元组 SQL-DML
- 利用 SQL 语言进行简单查询
- 单表查询 - SELECT-FROM-WHERE
- 检索条件的书写
- 结果唯一性问题
- 结果排序问题
- 模糊查询问题
- 多表联合查询
- 利用SQL语言进行增-删-改
- SQL-之 INSERT
- SQL-之 DELETE
- SQL-之 UPDATE
- 利用 SQL 语言修正与撤销数据库
- 内容回顾
- 练习
SQL 语言概述
【重点与难点】
- SQL-DDL 的基本语句:
CREATE DATABASE
,CREATE TABLE
- SQL-DML 的基本语句:
INSERT
,DELETE
,UPDATE
,SELECT
- SQL-SELECT 语句的训练:正确表达各种 查询 需求。
SQL 语言提出和发展
SQL 语言的功能概述
SQL 语言是集 DDL、DML 和 DCL 于一体的数据库语言;
SQL 语言主要由以下9个单词引导的操作语句来构成,但每一种语句都能表
达复杂的操作请求:
- DDL 语句引导词:
Create
(建立),Alter
(修改),Drop
(撤消)
模式的定义和删除,
- 包括定义 Database,Table,View,Index, 完整性约束条件等,
- 也包括定义对象(RowType 行对象,Type 列对象)
- DML 语句引导词:
Insert
(插入),Delete
(删除),Update
(更新),Select
(选择)
- 各种方式的更新与检索操作,如直接输入记录,从其他 Table(由 SubQuery
建立)输入;- 各种复杂条件的检索,如连接查找,模糊查找,分组查找,嵌套查找等;
- 各种聚集操作,求平均、求和、…等,分组聚集,分组过滤等;
- DCL 语句引导词:
Grant
(授权),Revoke
(撤销授权)
安全性控制:授权和撤消授权
利用 SQL 语言建立数据库
学生选课数据库 SCT
后面要反复使用它们!
- 学生:学号
S#
, 姓名Sname
, 性别Ssex
, 年龄Sage
, 所属系别D#
,班级Sclass
Student ( S# char(8), Sname char(10), Ssex char(2), Sage integer, D# char(2), Sclass char(6) )
- 院系:系别
D#
, 系名Dname
, 系主任Dean
Dept ( D# char(2), Dname char(10), Dean char(10) )
- 课程:课号
C#
, 课名Cname
, 教师编号T#
, 学时Chours
,学分Credit
Course ( C# char(3), Cname char(12), Chours integer, Credit float(1), T# char(3) )
- 教师:教师编号
T#
,教师名Tname
, 所属院系D#
,工资Salary
Teacher ( T# char(3), Tname char(10), D# char(2), Salary float(2) )
- 选课:学号
S#
, 课号C#
, 成绩Score
SC ( S# char(8), C# char(3), Score float(1) )
建立数据库 包括 两件事:定义数据库和表(使用 DDL),向表中追加元组(使用 DML)。
1. 定义数据库和表 SQL-DDL
DDL data Definition Language
,DDL 通常由 DBA 来使用,也有经 DBA 授权后由应用程序员来使用。
- 创建数据库 (DB) —
Create Database
- 创建 DB 中的 Table(定义关系模式) —
Create Table
创建数据库的语句—Create Database
数据库(Database) 是若干 具有相互关联关系 的 Table/Relation 的集合。
数据库可以看作是一个集中存放若干 Table 的大型文件。
create database
的简单语法形式:
create database 数据库名;
示例:创建课程学习数据库 S C T \mathbf {SCT} SCT
create database SCT;
创建关系/表的语句—Create Table
create table
简单语法形式:
Create table 表名( 列名 数据类型 [Primary key | Unique] [Not null]
[, 列名 数据类型 [Not null], … ] );
[ ]
表示其括起的内容可以省略,|
表示其隔开的两项可取其一。Primary key
:主键约束。每个表只能创建一个 主键约束。Unique
:唯一性约束(即候选键)。可以有 多个唯一性约束。Not null
:非空约束。是指该列允许不允许有空值出现,如选择了Not null
表明 该列不允许有空值出现。
在 SQL-92 标准中定义的数据类型:
char (n)
:固定长度 的字符串;varchar (n)
:可变长 字符串;int
:整数,有时不同系统也写作integer
;numeric (p, q)
:固定精度数字,小数点左边 p 位,右边 p-q 位;real
:浮点精度数字,有时不同系统也写作float(n)
,小数点后保留 n 位;date
:日期 (如 2003-09-12)time
:时间 (如 23:15:003)
和高级语言的数据类型,总体上是一致的,但也有些差异。
【示例】定义学生表 S t u d e n t \mathbf{Student} Student
Create Table Student ( S# char(8) not null , Sname char(10),
Ssex char(2), Sage integer, D# char(2), Sclass char(6) );
【示例】定义课程表 C o u r s e \mathbf{Course} Course
Create Table Course ( C# char(3) , Cname char(12), Chours integer,
Credit float(1), T# char(3) );
以此类推定义其他的表!定义了表后,就可向表中追加元组了!
2. 向表中追加元组 SQL-DML
DML Data Manipulation Language
,DML 通常由用户或应用程序员使用,访问经授权的数据库。
- 向 Table 中追加新的元组:
insert into
insert into
简单语法形式:
insert into 表名[ (列名 [, 列名 ]… ]
values (值 [, 值] , …) ;
values
后面值的排列,须与 into
子句后面的列名排列一致。
若表名后的所有列名省略,则 values
后的值的排列,须与该表存储中的列名排列一致。
【示例】追加学生表中的元组
insert into Student
values ( ‘98030101’ , ‘张三’, ‘男’, 20, ’03’, ‘980301’);
insert into Student ( S#, Sname, Ssex, Sage, D# , Sclass)
values ( ‘98030102’ , ‘张四’, ‘女’, 20, ’03’, ‘980301’);
【示例】追加课程表中的元组
insert into Course /*所有列名省略,须与定义或存储的列名顺序一致
values ( ‘001’ , ‘数据库’, 40, 6, ’001’);
insert into Course(Cname, C#, Credit, Chours, T#) /*如列名未省略,须与语句中列名的顺序一致
values (‘数据库’, ‘001’, 6, 40, ‘001’);
数据库建立完成后关键是要用呀!
利用 SQL 语言进行简单查询
- SQL 的
SELECT
子句 对应 关系代数的 投影 Π \Pi Π 操作; - SQL 的
FROM
子句 对应 关系代数的 笛卡尔积 × × × 操作; - SQL 的
WHERE
子句 对应 关系代数的 选择 σ \sigma σ 操作; GROUP BY
子句是 分组 操作。
单表查询 - SELECT-FROM-WHERE
SQL提供了结构形式一致但功能多样化的 检索语句 select
。
select
的简单语法形式:
select 列名 [[, 列名] … ]
from 表名
[ where 检索条件 ] ;
语义:从表名所给出的表中,查询出满足检索条件的元组,并按给定的列名
及顺序进行投影显示。
相当于:
select
语句中的 select …
, from…
, where…
, 等被称为 子句,在以上基本形式基础上会增加许多构成要素,也会增加许多新的子句,满足不同的需求。
【示例】检索学生表中所有学生的信息
// 第一种
select S#, Sname, Ssex, Sage, Sclass, D#
from Student ;
// 第二种
select * from Student ; //如投影所有列,则可以用 *来简写
【示例】检索学生表中所有学生的姓名及年龄
select Sname, Sage //投影出某些列
from Student ;
【示例】检索学生表中所有年龄小于等于19岁的学生的年龄及姓名
select Sage, Sname //投影的列可以重新排定顺序
from Student
where Sage <= 19;
检索条件的书写
- 与选择运算
σ
c
o
n
(
R
)
\sigma_{con}( \mathbf R)
σcon(R) 的条件
c
o
n
con
con 书写一样,只是其逻辑运算符用
and
,or
,not
来表示,同时也要注意运算符的优先次序及括弧的使用。 - 书写要点是注意对自然语言检索条件的正确理解。
【示例】求或者学过001
号课程,或者 学过002
号课程的学生的学号
select S#
from SC
where C# = ‘001’ OR C#=‘002’;
【示例】求 既 学过001
号课程,又 学过002
号课程的学生的学号
select S#
from SC
where C# = ‘001’ AND C#=‘002’;
//正确的SQL语句在讲义后面的示例中讲
【示例】检索教师表中所有工资 少于1500
元 或者 工资 大于2000
元,并且 是03
系的教师姓名?
select Tname
from Teacher
where (Salary < 1500 or Salary > 2000) and D# = ’03’;
结果唯一性问题
关系模型不允许出现重复元组。但现实 DBMS,却允许出现重复元组,但也允许无重复元组。
- 在 Table 中要求无重复元组 是通过定义
Primary key
或Unique
来保证的; - 而 在检索结果中要求无重复元组,是通过
DISTINCT
保留字的使用来实现的。
【示例】在选课表中,检索成绩 大于80
分的所有学号
select S#
from SC
where Score > 80 ; //有重复元组出现,比如一个同学两门以上课程大于80
select DISTINCT S#
from SC
where Score > 80; //重复元组被 DISTINCT 过滤掉,只保留一份
结果排序问题
DBMS 可以对检索结果进行排序,可以 升序排列,也可以 降序排列。
select
语句中结果排序是通过增加 order by
子句实现的:
order by 列名 [asc | desc]
意义为检索结果按指定列名进行排序,若
- 后跟
asc
或省略,则为升序; - 若 后跟
desc
,则为降序。
【示例】按学号 由小到大的顺序 显示出所有学生的学号及姓名
select S#, Sname
from Student
order by S# asc ;
【示例】检索 002
号课 大于 80
分的所有同学学号并按成绩 由高到低顺序显示
select S#
from SC
where C# = ‘002’ and Score > 80
order by Score desc ;
模糊查询问题
比如检索姓于的学生,检索于某某;
这类查询问题,select
语句是通过在检索条件中引入运算符 like
来表示的。
含有 like
运算符的表达式:
列名 [not] like “字符串”
意义:找出 匹配给定字符串的字符串,其中给定字符串中可以出现 %
, _
等匹配符。
匹配规则:
%
匹配 零个或多个 字符;_
匹配 任意单个 字符;\
转义字符,用于 去掉一些特殊字符的特定含义,使其被作为普通字符看待,如用\%
去匹配字符%
,用\_
去匹配字符_
。
【示例】检索所有姓 于
的学生学号及姓名
select S#, Sname
from Student
where Sname like ‘于%’ ;
【示例】检索名字为 于
某某的所有同学姓名
select Sname
from Student
where Sname like ‘于_ _’;
【示例】检索名字不姓 于
的所有同学姓名
select Sname
from Student
where Sname not like ‘于%’;
多表联合查询
多表联合检索可以通过 连接运算 来完成,而连接运算又可以通过 广义笛卡尔积 后再进行选择运算来实现。
select
的多表联合检索语句:
select 列名 [ [, 列名] … ]
from 表名1, 表名2, …
where 检索条件 ;
相当于
检索条件中要包含连接条件,通过不同的连接条件可以实现等值连接、不等值连接及各种 θ \theta θ-连接。
θ \theta θ-连接之等值连接
【示例】按 “001”
号课成绩 由高到低顺序 显示所有学生的姓名(二表连接)
select Sname
from Student, SC
where Student.S# = SC.S# and SC.C# = ‘001’
order by Score desc;
多表连接时,如两个表的属性名相同,则需采用 表名. 属性名
方式来限定该
属性是属于哪一个表。
【示例】按 ‘数据库’
课成绩 由高到低顺序 显示所有同学姓名(三表连接)
select Sname from Student, SC, Course
where Student.S# = SC.S# and SC.C# = Course.C# and Cname = ‘数据库’
order by Score desc;
连接运算涉及到 重名 的问题,如两个表中的属性重名,连接的两个表重名
(同一表的连接)等,因此需要使用 别名 以便区分。
select
中采用别名的方式:
select 列名 as 列别名 [ [, 列名 as 列别名] … ]
from 表名1 as 表别名1, 表名2 as 表别名2, …
where 检索条件 ;
上述定义中的 as
可以省略,当定义了别名后,在检索条件中 可以使用别名来限定属性。
θ \theta θ-连接之不等值连接
【示例】求有薪水差额的任意两位教师
select T1.Tname as Teacher1, T2.Tname as Teacher2
from Teacher T1, Teacher T2
where T1.Salary > T2.Salary ;
【示例】求年龄有差异的任意两位同学的姓名
select S1.Sname as Stud1, S2.Sname as Stud2
from Student S1, Student S2
where S1.Sage > S2.Sage ;
有时表名很长时,为书写条件简便,也定义表别名,以简化书写。
多表联合查询训练
【示例】求 既 学过 “001”
号课 又 学过 “002”
号课的所有学生的学号
select S1.S# from SC S1, SC S2
where S1.S# = S2.S# and S1.C#=‘001’ and S2.C#=‘002 ;
【示例】求 “001”
号课成绩比 “002” 号课成绩高的所有学生的学号
select S1.S#
from SC S1, SC S2
where S1.S# = S2.S# and S1.C#=‘001’ and S2.C#=‘002’ and S1.Score > S2.Score;
【示例】列出 没学过 李明老师讲授课程的所有同学的姓名
select Sname
from Student S, SC, Course C, Teacher T
where T.Tname <> ‘李明’ and C.C# = SC.C# and SC.S# = S.S# and T.T# = C.T#;
// 以上是错误答案,正确的SQL语句在下面
利用SQL语言进行增-删-改
- 元组新增
Insert
:新增 一个或一些 元组 到数据库的 Table 中; - 元组更新
Update
:对某些元组中的某些 属性值 进行 重新设定; - 元组删除
Delete
:删除 某些 元组。
- SQL-DML 既能单一记录操作,也能对记录集合进行批更新操作;
- SQL-DML之更新操作需要利用前面介绍的子查询(Subquery)的概念,以便处理
“一些”
、“某些”
等。
SQL-之 INSERT
元组新增 insert
命令有两种形式:
- 单一元组 新增命令形式:插入 一条指定元组值 的元组;
insert into 表名 [(列名[,列名]…)]
values (值 [,值]…);
- 批数据 新增命令形式:插入 子查询结果 中的若干条元组,待插入的元
组由子查询给出。
insert into 表名 [(列名[,列名]…)]
子查询;
【示例】单一元组新增
insert into Teacher (T#, Tname, D#, Salary)
values (“005”, “阮小七”, “03”, “1250”);
insert into Teacher
values (“006”, “李小虎”, “03”, “950”);
【示例】批元组新增
新建立 Table: St(S#, Sname)
,将检索到的满足条件的同学新增到该表中:
insert into St (S#, Sname)
select S#, Sname
from Student
where Sname like ‘%伟 ’ ;
insert into St (S#, Sname)
select S#, Sname
from Student
order by Sname;
【注意】当 新增元组 时,DBMS 会 检查用户定义的完整性约束条件 等,如不符合完整性约束条件,则将不会执行新增动作。
【示例】新建 Table: SCt(S#, C#, Score)
,将检索到的成绩及格同学的记录新增到该表中
insert into SCt (S#, C#, Score)
select S#, C#, Score
from SC
where Score>=60 ;
【示例】追加成绩优秀同学的记录
insert into SCt (S#, C#, Score)
select S#, C#, Score
from SC
where Score>=90 ;
- 还可以有更复杂的
“查询后插入到新表中”
的语句,例如可以 将中间结果存储成表 ----这很有用!
【示例】新建 Table: St(S#, Sname, avgScore)
,将检索到的同学的平均成绩 新增 到该表中
insert into St (S#, Sname, avgScore)
select S#, Sname, Avg(Score)
from Student, SC
where Student.S# = SC.S#
group by Student.S# ;
此
SELECT
语句的书写语法后面再解释。
SQL-之 DELETE
- 元组删除
Delete
命令:删除满足指定条件的元组。
delete from 表名
[ where 条件表达式] ;
- 如果
Where
条件省略,则删除所有的元组。
【示例】删除 S C \mathbf {SC} SC 表中所有元组
delete from SC ;
【示例】删除 98030101
号同学所选的所有课程
delete from SC
where S# = ‘98030101’ ;
【示例】删除 自动控制系
的所有同学
delete from Student
where D# in ( select D# from Dept where Dname = ‘自动控制’);
----此是一简单的 嵌套子查询,后面会有更详细解释。
- 还可以有更复杂的
“条件控制的删除”
语句,----这很有用!
【示例】删除有四门不及格课程的所有同学
delete from Student
where S# in
( select S# from SC where Score < 60
group by S# having count(*)>= 4 );
当 删除元组 时,DBMS 会检查 用户定义的完整性约束条件 等,如不符合完整性约束条件,则将不会执行删除动作。
SQL-之 UPDATE
- 元组更新
Update
命令:用指定要求的值更新指定表中满足指定条件的元组的指定列的值。
update 表名
set 列名 = 表达式 | (子查询) [ [ , 列名 = 表达式 | (子查询) ] … ]
[ where 条件表达式] ;
- 如果
Where
条件省略,则更新所有的元组。
【示例】将所有教师工资上调5%
update Teacher
set Salary = Salary * 1.05 ;
【示例】将所有计算机系的教师工资上调10%
update Teacher
set Salary = Salary * 1.1
where D# in
( select D# from Dept where Dname = ‘计算机’);
- 还可以有更复杂的
“条件控制的更新”
语句,----这很有用!
【示例】当某同学 001
号课的成绩 低于 该课程平均成绩时,将该同学该门课成绩提高5%
update SC
set Score = Score * 1.05
where C# = ‘001’ and Score < some
( select AVG(Score) from SC
where C# = ‘001’ ) ;
【示例】将张三同学 001
号课的成绩置为其班级该门课的平均成绩
update SC
set Score = ( select AVG(SC2.Score)
from SC SC1, Student S1, SC SC2, Student S2
where S1.Sclass = S2.Sclass and SC1.S# = S1.S#
and SC2.S# = S2.S# and S1.Sname=‘张三’
and SC1.C# = SC2.C# and SC1.C# = ‘001’ )
where C# = ‘001’ and S# in ( select S# from Student
where Sname = ‘张三’ ) ;
利用 SQL 语言修正与撤销数据库
修正数据库:修正数据库的定义,主要是修正表的定义。
- 修正基本表的定义:
alter table tablename
[add {colname datatype, …}] #增加新列
[drop {完整性约束名}] #删除完整性约束
[modify {colname datatype, …}] #修改列定义
【示例】在学生表 Student(S#,Sname,Ssex,Sage,D#,Sclass)
基础上 增加二列 Saddr
, PID
alter table Student
add Saddr char[40], PID char[18] ;
【示例】将上例表中 Sname
列的 数据类型改为10个字符
alter table Student
modify Sname char(10) ;
【示例】删除 学生姓名 必须取唯一值 的 约束
alter table Student
drop unique( Sname );
- 撤消基本表:
drop table 表名
【示例】撤消学生表 S t u d e n t \mathbf{Student} Student
drop table Student;
【示例】撤消教师表 T e a c h e r \mathbf{Teacher} Teacher
drop table Teacher;
【注意】SQL- delete
语句只是删除表中的元组,而撤消基本表 droptable
的操作是 撤消包含表格式、表中所有元组、由该表导出的视图等相关的所有内
容,所以使用要特别注意。
Delete…From
与Drop table
的区别清楚了吗 ?!!!
- 撤消数据库:
drop database 数据库名;
【示例】撤消 S C T \mathbf{SCT} SCT 数据库
drop database SCT;
有些 DBMS 提供了操作多个数据库的能力,此时在进行数据库操作时需要指定待操作数据库与关闭数据库的功能。
- 指定 当前 数据库
use 数据库名;
- 关闭 当前数据库
close 数据库名;
内容回顾
练习
正确答案:A
正确答案:A
正确答案:A
正确答案:A
正确答案:A
正确答案:A
正确答案:A
正确答案:A
正确答案:A
正确答案:A
正确答案:A
正确答案:A
正确答案:A
正确答案:A
正确答案:A
正确答案:A
正确答案:A
正确答案:A
正确答案:A
【解析】WHERE Student.S# = SC.S# AND Course.C# = SC.C# AND T# = 'T01' AND Score<60
表示学过T01
号教师讲授课程且成绩小于60
,所以整个语句表示学习T01
号教师讲授课程不及格的所有学生的姓名。
正确答案:A
【解析】更新表中的数据要用UPDATE
操作,正确的格式是:UPDATE 表名 SET 列名=新值 WHERE 列名=某值
,课号是 字符型 的,所以要 加引号。
正确答案:A
【解析】删除某行要用DELETE
,正确的格式是:DELETE FROM 表名 WHERE 列名=某值
,课号是 字符型的,所以要 加引号。
正确答案:A
【解析】只查询“课号”
,所以只有一列,DISTINCT
表示相同的值只显示一条。
正确答案:A
正确答案:A
【解析】
WHERE
子句对应关系代数的 选择 σ \sigma σ 操作;SELECT
子句对应关系代数的 投影 Π \Pi Π 操作;FROM
子句对应关系代数的 笛卡尔积 × × × 操作;GROUP BY
子句是 分组 操作。
正确答案:A
正确答案:A
【解析】检索结果为空。