跳到主要内容

sql

简单查询

基本语法

  • FROM 子句确定查询表;
  • WHERE 子句约束元组查询条件;
  • SELECT 约束查询属性;
SELECT *
FROM Movies
WHERE studioName="Disney";

投影操作

投影操作
  • 限定 SELECT 子句;
SELECT title, length
FROM Movies
WHERE studioName="Disney";
属性别名
SELECT title AS name,length AS duration
FROM Movies
WHERE studioName="Disney";

选择操作

选择操作
  • 限定 WHERE 子句;
SELECT title AS name,length AS duration
FROM Movies
WHERE studioName="Disney" AND year = 1990;

排序

  • 使用 ORDER BY 子句;
  • 使用 ASC 和 DESC 设置排序顺序,默认为 ASC;
  • 排序操作最后执行;
SELECT title AS name,length AS duration
FROM Movies
WHERE title LIKE "Star__";
ORDER BY length, title;

运算表达式

比较运算
  • =;
  • <>;
  • <;
  • > ;
  • <=;
  • >=;
布尔运算
  • AND;
  • OR;
  • NOT;
字符串比较
  • 使用比较运算符;
  • 比较字母顺序;
模式匹配
  • 使用 LIKE 操作符;
  • % 表示任意长度的字符;
  • _ 表示任意一个字符;
SELECT title AS name,length AS duration
FROM Movies
WHERE title LIKE "Star__";

空值

空值解释
  • 未知值;
  • 不适用的值;
  • 保留值;
运算规则
  • NULL 进行算术运算结果仍为 NULL;
  • NULL 比较结果为 UNKNOWN;

布尔值

  • TRUE;
  • FALSE;
  • UNKNOWN:或真或假;

多关系查询

笛卡尔积

  • FROM 子句中引入多个表;
SELECT title AS name,length AS duration
FROM Movies, MovieExec
WHERE title="StarWars" AND producerC=cert;

消除同名属性

  • R.A 表示关系 R 的属性 A;
SELECT MovieStar.name, MovieExec.name
FROM MovieStar, MovieExec
WHERE MovieStar.address = MovieExec.address;

表重命名

  • 修改 FROM 子句;
SELECT Star1.name,Star2.name
FROM MovieStar Star1, MovieStar Star2
WHERE Star1.address = Star2.address

查询的并, 交, 差

(SELECT name,address FROM MovieStar WHERE gender="F")
UNION
(SELECT name,address FROM MovieExec WHERE netWorth>10000000);
(SELECT name,address FROM MovieStar WHERE gender="F")
INTERSECT
(SELECT name,address FROM MovieExec WHERE netWorth>10000000);
(SELECT name,address FROM MovieStar WHERE gender="F")
EXCEPT
(SELECT name,address FROM MovieExec WHERE netWorth>10000000);

子查询

子查询

  • 查询 A 是查询 B 的一部分;
  • 查询 A 称作子查询;
  • 子查询可有下一级子查询;

产生标量值的子查询

  • 首先执行子查询;
  • 子查询返回一个原子值;
  • 返回值作为外层查询的查询条件;
SELECT name
FROM MovieExec
WHERE cert=(
SELECT producerC FROM Movies WHERE title="Star Wars"
);

关系的条件表达式

条件表达式含义
EXISTS RR 非空返回真值
s IN Rs 为 R 中的某个值返回真值
s NOT IN Rs 不为 R 中的某个值返回真值
s > ALL Rs 大于 R 中的所有值返回真值, 其余比较运算符同理
NOT (EXISTS/ALL/ANY)结果取反

元组的条件表达式

  • 括号包裹的原子值或属性;
  • 比较元组的条件表达式时,根据顺序依次比较;
-- 子查询 1
-- 找出 StarsIn 中 starName 为 Harrison Ford 的元组
-- 提取所有的 (movieTitle,movieYear) 集合
-- 子查询 2
-- 检索 Movies 所有元组,其 (title,year) 在子查询 1 的查询结果中
-- 提取子查询 2 所有满足条件的元组的 producerC 属性值集合
-- 主查询
-- 找出 MovieExec 中 cert 等于子查询 2 属性值集合任意值的元组
-- 提取所有满足查询条件的元组的 name 属性值
SELECT name
FROM MovieExec
WHERE cert=(
SELECT producerC
FROM Movies
WHERE (title, year) IN (
SELECT movieTitle, movieYear
FROM StarsIn
WHERE starName="Harrison Ford"
)
);

关联子查询

  • 一个子查询计算多次;
  • 子查询中某项为上级查询中某个元组变量的值;
SELECT title
FROM MoviesOld WHERE year < ANY (
SELECT year
FROM Movies
WHERE title=Old.title
);

FROM 子句中的子查询

  • 查询结果必须使用别名
SELECT name
FROM MovieExec, (
SELECT producerC#
FROM Movies, StarsIn
WHERE title=movieTitle AND year =movieYear
) Prod
WHERE cert#=Prod.producerC#;

连接

交叉连接
  • 作用于 FROM 子句;
  • 使用 CROSS JOIN 操作符;
  • 等效于笛卡尔积;
SELECT name
FROM Movies CROSS JOIN StarsIn
θ\theta 连接
  • 作用于 FROM 子句;
  • 使用 JOIN 。。.ON 操作符;
  • JOIN 笛卡尔积两张表;
  • ON 为筛选条件;
SELECT title, length
FROM Movies JOIN StarsIn ON title=movieTitle AND year=movieYear;
自然连接
  • 作用于 FROM 子句;
  • 使用 NATURAL JOIN 操作符;
SELECT name
FROM Movies NATURAL JOIN StarsIn
外连接
  • 作用于 FROM 子句;
  • 使用 FULL/RIGHT/LEFT OUTER JOIN 操作符;
  • NULL 填充悬浮元祖;
SELECT name
FROM Movies FULL OUTER JOIN StarsIn

全关系操作

消除重复

  • 使用 DISTINCT 关键字;
  • 耗费极大;
SELECT DISTINCT name
FROM Movies FULL OUTER JOIN StarsIn

交, 并, 差中的重复

  • 默认消除重复;
  • 若保留重复使用 ALL 关键字;
(SELECT name,address FROM MovieStar WHERE gender="F")
UNION ALL
(SELECT name,address FROM MovieExec WHERE netWorth>10000000);

聚集操作符

  • SUM:求和;
  • AVG:平均值;
  • MIN:最小值;
  • MAX:最大值;
  • COUNT:元组数量;
SELECT AVG(netWorth)
FROM MovieExec;

-- 消除重复
SELECT COUNT(DISTINCT starName)
FROM StarsIn;

分组

  • 使用 GROUP BY 子句;
  • 关系根据 GROUP BY 子句中的属性分组;
  • 聚集操作符作用于各分组上;
SELECT studioName,SUM(length)
FROM Movies
GROUP BY studioName;

分组, 聚集和空值

  • NULL 在聚集操作中被忽视,COUNT 为 0,其余均为 NULL;
  • NULL 分组中作为一般值看待;

HAVING 子句

  • 作用于 GROUP BY 之后;
  • 筛选指定条件的分组;
SELECT name,SUM(length)
FROM MovieExec,Movies
WHERE producerC#=cert#
GROUP BY name
HAVING MIN(year)<1930;

SQL 查询子句顺序

  • SELECT;
  • FROM;
  • WHERE;
  • GROUP BY;
  • HAVING;
  • ORDER BY;

数据库更新

插入元组

  • INSERT INTO R(A1,...,An) VALUES (U1,...,Un)
INSERT INTO StarsIn
VALUES("The Maltese Falcon",1942,"Sydney Greenstreet");

删除元组

  • DELETE FROM R WHERE <条件>
DELETE FROM MovieExec
WHERE netWorth<10000000;

修改元组

  • UPDATE R SET <新值赋值> WHERE <条件>
UPDATE MovieExec
SET name = "Pres"
WHERE cert# IN (
SELECT presC#
FROM Studio
);

事务

事务

  • 原子性的数据库操作的集合;
    • 事务中的操作要么全部执行,要么都不执行;
  • 事务是可串行化的;
    • 同一时刻只有一个事务执行;
  • 数据库通过事务解决并发操作导致的错误问题;

只读事务

  • 只有读操作的事务;
  • 不会修改数据库;
  • 只读事务可以并行执行;
-- 下一条事务为只读事务
SET TRANSACTION READ ONLY;
-- 下一条事务可写
SET TRANSACTION READ WRITE

脏数据

脏数据
  • 事务中写入,但未提交的数据;
  • 事务一旦失败,脏数据立刻移除;
脏读
  • 对于事务产生的脏数据的读取操作;
-- 设置数据库事务读取其他事务脏数据
SET TRANSACTION READ WRITE
ISOLATION LEVEL READ UNCOMMITTED;

隔离层次

  • 规定事务之间的操作;
    • 可串行化:默认隔离层次;
    • 读未提交:允许脏读;
    • 读提交:禁止脏读,允许该隔离层次的事务多次进行查询操作得到不同答案;
    • 可重复读:禁止脏读,假定该隔离层次的事务多次进行查询操作得到相同答案;
-- 可串行化
ISOLATION LEVEL SERIALIZABLE;
-- 读未提交
ISOLATION LEVEL READ UNCOMMITTED;
-- 读提交
ISOLATION LEVEL READ COMMITTED;
-- 可重复读
ISOLATION LEVEL REPEATABLE READ;