SQL语言
简单,易学。
定义模式、表
- 建立关系模式
- 修改关系模式
- 删除关系模式
查询
SELECT [ALL|DISTINCT] <目标列表达式>
FROM <表名>
[WHERE <条件表达式>]
[GROUP BY <列名1> [HAVING <条件表达式>]]
[ORDER BY <列名2> [ASC|DESC]]
单表查询
查询仅涉及一个表,是一种最简单的查询操作。
选择列
即不用WHERE子句,仅使用SELECT,FROM子句。
一般情况下,用于查询指定列
还可以查询全部的列
可以查询经过计算的指
SELECT Sname, 2022-Sage FROM Student;
即可查询出姓名属性、以及2022减去年龄属性的值
可以通过DISTINCT或者ALL来选择是否去除相同的列
可以实现列的重命名(列别名)
SELECT Sname NAME, 2022-Sage BIRTHDAY, LOWER(Sdept) FROM Student;
WHERE:查询元组
WHERE子句常用的是条件表达式,涉及的谓词很多,常见的是比较、确定集合等。
- 比较:=,>, <, >=, <=, <>
- 确定集合:IN, NOT IN
- 多重条件:AND, OR
- 字符匹配:LIKE, NOT LIKE
下面给出几个实例对where子句的基本使用进行说明:
DISTINCT短语的作用范围是所有目标列
SELECT DISTINCT Cno, Grade FROM SC;
而下面的写法是错误的:
SELECT DISTINCT Cno, DISTINCT Grade FROM SC;
between的使用
筛选出Student关系中年龄在19到21之间的同学的姓名和性别
SELECT Sname, Ssex FROM Student Where sage between 19 and 21;
like的使用
查询姓“东方”的学生:
SELECT * FROM Student WHERE Sname like '东方%';
通配符:
- %:代替零个或者多个字符
- _:仅代替一个字符
当要查询的字符串本身就含有%或者_时,需要使用ESCAPE短语进行转义。
in的使用
查询数学系和计算机系的学生:
SELECT * FROM Student WHERE Sdept in ('MA', 'CS');
ORDER BY:对查询结果进行排序
ASC:升序,排序列为空值的元组最后显示
DESC:降序(默认),排序列为空值的元组最先显示
聚集函数
- COUNT(*) 统计元组个数
- SUM([DISTINCT | ALL] < 列名 >) 计算一列值的总和
- AVG… 计算平均值
GROUP BY:对结果进行分组
按指定的一列或者多列值分组,值相等的分为一组。
注意,使用了GROUP BY子句之后,SELECT子句的列名列表中只能出现分组属性和聚集函数。
当然,有时还会使用HAVING短语筛选最终输出结果,如
SELECT dept_name, Max(salary)
FROM Employee
WHERE age>=23
GROUP BY dept_name
HAVING Max(salary)>=80000;
HAVING短语和WHERE子句都有筛选功能,但是两者有很大的区别——在作用对象上。
- HAVING短语筛选的作用对象是分组后的中间表,从中选择满足条件的分组;
- WHERE子句筛选的作用对象是基表,从中选择满足条件的元组。
连接查询
连接查询,即多表查询情况,待查询的表不只一张。
用来连接两个表的条件称为连接条件或者连接谓词。
θ-连接
使用SELECT-FROM-WHERE表示,WHERE子句中包括连接多个表的条件,即连接条件:
SELECT * FROM Student, SC WHERE Student.Sno = SC.Sno;
使用JOIN ON表示方法:
SELECT * FROM Student JOIN SC ON Student.Sno = SC.Sno WHERE Sage < 21;
自然连接,使用natural join关键字:
SELECT Student.Sno, Sname, Sage, Sdept, Cno, Grade FROM Student NATURAL JOIN SC;
自连接,一般需要给表起别名,以示区别。
SELECT FIRST1.Cno, SECOND1.Cpno FROM Course FIRSE1, Course SECOND1 WHERE FIRST1.Cpno = SECOND1.Cno
集合查询
利用集合操作,对查询结果进行集合运算:
- 并 UNION
- 交 INTERSECT
- 差 EXCEPT
对于并、交集合查询,其思想与集合运算一致:
SELECT DISTINCT *
FROM Student
WHERE Sdept='CS' OR Sage<=19;
SELECT *
FROM Student
WHERE Sdept='CS'
UNION
SELECT *
FROM Student
WHERE Sage<=19;
数据插入
格式:
INSERT
INTO 表名(属性1, 属性2, ...)
VALUES 元组
将元组插入表中,如果列名列表省略不写,则默认是插入全部属性,否则按照声明的列名属性插入元组,其他没有在INTO属性中出现的属性列,取空值。
Student表如下:
学号 Sno | 姓名 Sname | 性别 Ssex | 年龄 Sage | 所在系 Sdept |
---|---|---|---|---|
20220900112 | 孙承宗 | 男 | 29 | 翰林 |
20229180938 | 徐阶 | 男 | 49 | 内阁 |
20221920709 | 袁崇焕 | 男 | 39 | 兵部 |
20221102123 | 张居正 | 男 | 48 | 内阁 |
SC表如下:
学号Sno | 课程号Cno | 成绩Grade |
---|---|---|
20220900112 | 1 | 98 |
20220900112 | 2 | 92 |
20221102123 | 1 | 90 |
INSERT
INTO Student
VALUES('20201110227', '张江陵', '男', 19, '内阁');
-- 向Student表格中添加一行数据
INSERT
INTO Student(Sno, Sname, Sdept)
VALUES('20222900767', '徐文长', '师爷');
DBMS会检查所插入元组是否破坏已定义的完整性约束
- 实体完整性:是否插入了主键相同的元组
- 参照完整性(关联完整性):外键表插入新元组时,新元组的外键值是否在主键表中存在
- 用户定义的完整性:
- 对于有NOT NULL约束的属性列,是否提供了非空值
- 对于有UNIQUE约束的属性列,是否提供了非重复值
- 对于有值域约束的属性列,所提供的属性值是否在值域范围内
修改数据
UPDATE 表名
SET <列名> = <表达式>...
[WHERE <条件>];
功能:修改指定表中满足where子句条件的元组
SET子句:指定修改方式
WHERE子句:指定要修改的元组
-- 将上面的Student表中袁崇焕的所在系改为‘督师蓟辽’
UPDATE Student
SET Sdept='督师蓟辽'
WHERE Sname='袁崇焕';
注意:修改数据的同时DBMS会做完整性检查(比如涉及外键表时的参照完整性)。
删除数据
DELETE
FROM <表名>
[WHERE <条件>]
同样的,DBMS在执行删除语句时,也会检查所删除的元组是否破坏表上已定义的完整性规则。
- 删除单个元组的值
- 删除多个元组的值
- 带子查询的删除语句
比如,删除上面的Student表格中“内阁”所有成员的选课记录(SC表格)。
DELETE
FROM Student
WHERE Sno IN
(SELECT Sno
FROM Student
WHERE Student.Sdept = '内阁');
视图
何为视图
视图与基本表在形式上几乎没有区别,同样支持各种SQL操作。
视图可以理解为数据库的“窗口”。通过视图,不同的人可以观察到自己感兴趣的数据项,而不需要观察整个数据库表。
基本语法格式
CREATE VIEW <视图名> [(<列名>...)]
AS <子查询>
[WITH CHECK OPTION];
- 每一个视图都有名称,放在VIEW后面声明,还可以声明视图的属性列;
- AS后面跟任意SELECT查询语句,表示视图中的数据来源;
- WITH CHECK OPTION表示,通过视图进行各种操作时,不得违反视图定义中子查询的谓词条件(条件表达式)。
视图消解
从数据字典中取出视图定义,把定义中的子查询和用户查询结合起来,转换成等价的对基表的查询,然后在基表上执行修改之后的查询,称为视图消解。
更新视图
由于视图本身并不具有数据存储功能,只是给用户提供展示数据,因此,对视图数据的更新,都是通过视图消解转为对基本表的更新。
但是,并不是所有的视图都可以被更新。
删除视图
DROP VIEW <视图名> [CASCADE];
如果要删除的视图还导出了其他视图,就需要指定CASCADE选项,表示级联删除。