SQL
Structured Query Language
Last updated on
数据定义
模式 Schema
CREATE SCHEMA ...
,
DROP SCHEMA ...
表 Table
CREATE TABLE ...
,
DROP TABLE ...
,
ALTER TABLE ...
视图 View
- 从一个或几个基本表导出的表(虚表)
- 数据库中只存放视图的定义而不存放视图对应的数据
- 视图是一个虚表
- 用户可以在视图上再定义视图
创建
CREATE VIEW IS_Student AS
SELECT Sno, Sname, Sage
FROM Student
WHERE Sdept = 'IS';
建立信息系学生的视图,并要求进行修改和插入操作时仍需保证该视图只有信息系的学生。
CREATE VIEW IS_Student AS
SELECT Sno, Sname, Sage
FROM Student
WHERE Sdept = 'IS'
WITH CHECK OPTION;
查询视图和查询表一样。
索引 Index
CREATE INDEX ...
,
DROP INDEX ...
,
ALTER INDEX ...
数据查询
SELECT
ALL ...
DISTINCT ...
FROM
后接表名,可以 AS ...
起别名,多表用 ,
分开。
WHERE
- 通用条件判断语句
LIKE
运算符%
任意长度(可以为 0)的字符串_
任意单个字符- 例如
SELECT Sname, Sno FROM Student WHERE Sname LIKE '_阳%';
- 如果要表示原本的
%
和_
字符使用\%
,\_
加上ESCAPE '\'
,例如
SELECT Cno, Ccredit FROM Course WHERE Cname LIKE 'DB\_Design' ESCAPE '\';
GROUP BY
& HAVING
HAVING
用于过滤 GROUP BY
的结果,
例如:查询选修了 3 门以上课程的学生学号
SELECT Sno FROM SC
GROUP BY Sno
HAVING COUNT(*) > 3;
ORDER BY
ASC
升序,默认的DESC
降序
聚集函数
SELECT COUNT(*) FROM Student;
中的 COUNT
是聚集函数
COUNT
DISTINCT
AVG
连接查询
- 简单连接查询
- 外连接查询
SELECT Student.Sno, Sname, Ssex, Sage, Sdept, Cno, Grade
FROM Student LEFT OUT JOIN SC ON (Student.Sno = SC.Sno);
嵌套查询
SELECT Sname FROM Student
WHERE Sno IN (
SELECT Sno FROM SC
WHERE Cno = '2'
);
限制:子查询不能使用 ORDER BY
语句,如果需要排序,
只能在主查询的结尾加 ORDER BY
。
- 不相关子查询:不依赖外层传入的值
- 相关子查询:依赖外层传入的值
连接查询与嵌套查询的区别:连接查询效率相对低一些 (因为需要做笛卡尔积)
集合查询
查询计算机科学系的学生及年龄不大于 19 岁的学生(并)。
SELECT * FROM Student
WHERE Sdept = 'CS'
UNION
SELECT * FROM Student
WHERE Sage <= 19;
UNION
自动去重UNION ALL
不去重
类似地, 查询计算机科学系的学生与年龄不大于 19 岁的学生(交)。
SELECT * FROM Student
WHERE Sdept = 'CS'
INTERSECT
SELECT * FROM Student
WHERE Sage <= 19;
类似地,EXCEPT
(差)。
基于派生表的查询
派生表:FROM
后面跟的不是表,而是一个子查询语句。
例如,找出每个学生超过他自己选修课程平均成绩的课程号:
SELECT Sno, Cno
FROM SC, (
SELECT Sno, Avg(Grade)
FROM SC GROUP BY Sno
AS Avg_sc(avg_sno, avg_grade)
)
WHERE SC.Sno = Avg_sc.avg_sno and
SC.Grade >= Avg_sc.avg_grade;
数据更新(增、删、改)
插入数据
- 插入元组
- 给出全部列的数据
INSERT INTO Student(Sno, Sname, Ssex, Sdept, Sage) VALUES ('201215128', '张三', '男', 'CS', 18);
- 自动赋空值
等价于INSERT INTO SC(Sno, Cno) VALUES ('201215128', '1');
INSERT INTO SC VALUES ('201215128', '1', NULL);
- 插入子查询结果
- 例如,对每个系,求学生的平均年龄,并把结果存入数据库
CREATE TABLE Dept_age ( Sdept CHAR(15), Avg_age INT ); INSERT INTO Dept_age(Sdept, Avg_age) SELECT Sdept, AVG(Sage) FROM Student GROUP BY Sdept;
修改数据
- 修改某一个元组的值
UPDATE Student SET Sage = 22 WHERE Sno = '201215121';
- 修改多个元组的值
UPDATE Student SET Sage = Sage + 1;
- 带自查询的修改语句
UPDATE SC SET Grade = 0 WHERE Sno IN ( SELECT Sno FROM Student WHERE Sdept = 'CS' );
删除数据
- 删除某一个元组的值
DELETE FROM Student WHERE Sno = '201215128';
- 删除多个元组的值
和DELETE FROM SC;
DROP TABLE SC;
的区别是这个会剩下空表。 - 带自查询的删除语句
DELETE FROM SC WHERE Sno IN ( SELECT Sno FROM Student WHERE Sdept = 'CS' );
空值
产生:INSERT
,UPDATE
判断:NOT NULL
空值的约束条件
属性定义中
NOT NULL
约束的不能是空值UNIQUE
约束的不能是空值PRIMARY KEY
不能是空值
空值的运算*
NULL
与另一个值(任意)的算术运算结果为NULL
NULL
与另一个值(任意)的比较运算结果为UNKNOWN
- 有
UNKNOWN
后,传统二值逻辑(TRUE
,FALSE
)就扩展成了三值逻辑
x | y | x AND y | x OR y | NOT x |
---|---|---|---|---|
T | T | T | T | F |
T | U | U | T | F |
T | F | F | T | F |
U | T | U | T | U |
U | U | U | U | U |
U | F | F | U | U |
F | T | F | T | T |
F | U | F | U | T |
F | F | F | F | T |
在查询语句中的例子:找出选修 1 号课程的不及格的学生
SELECT Sno FROM SC
WHERE Grade < 60 AND Cno = '1';
查询结果不包含缺考的学生,因为他们的 Grade
值为 NULL
。
找出选修 1 号课程的不及格及缺考的学生
SELECT Sno FROM SC
WHERE Cno = '1' AND
(Grade < 60 OR Grade IS NULL);