1. 数据查询
SELECT [ALL|DISTINCT]<目标列表达式>[,<目标列表达式>]…
FROM<表名或视图名>[,<表名或视图名>…]|(<SELECT语句>)[AS]<别名>
[WHERE<条件表达式>]
[GROUP BY<列名1>[HAVING<条件表达式>]]
[ORDER BY<列名2>[ASC|DESC]]
含义:
根据WHERE子句的条件表达式从FROM子句指定的基本表、视图或派生表中找出满足条件的元组,再按照SELECT子句中的目标列表达式选出元组中的属性值形成结果表
1.1. 单表查询(只涉及一个表)
1.1.1. 选择表中的若干列
通过SELECT语句
SELECT <目标列表达式>
FROM<表名或视图名>
<目标表达式>中的各个列的顺序可能与表中的顺序不一致,用户可以自定义显示的顺序
1.1.2. 选择表中的若干组
1. 消除取值重复的行:用DISTINCT语句
SELECT DISTINCT <目标列表达式>
FROM<表名或视图名>
2.查询满足条件的元组:用WHERE语句
SELECT<目标列表达式>
FROM<表名或视图名>
WHERE<条件表达式>
3. ORDER BY子句:查询结果按照某一顺序排列
升序(ASC)降序(DESC)
SELECT<目标列表达式>
FROM<表名或视图名>
[ORDER BY<排序列名>[ASC|DESC]]
4.聚集函数
SELECT<聚集函数>
FROM<表名或视图名>
5. GROUP BY子句:查询结果按照某一列或者多列的值分组,值相等的为一组
SELECT<目标列表达式>
FROM<表名或视图名>
GROUP BY<目标列>
1.2. 连接查询
之前的查询针对的是 一个表 ,但是如果针对 两个表 ,那么就成为 连接查询 。
1.2.1. 等值与非等值连接查询
连接查询的WHERE子句中用来连接两个表的条件称为连接条件或连接谓词
WHERE[<表名1>.]<列名1><比较运算符>[<表名2>.]<列名2>
比较运算符:= < > <= >= !=(相当于<>)
=:等值连接
其他的:非等值连接
连接谓词中的列名称为连接字段
各连接字段类型必须是可比的,但是不一定相同
WHERE[<表名1>.]<列名1>BETWEEN[<表名2>.]<列名2>AND[<表名2>.]<列名3>
查找方法:
每一个要查找元组 在 总表中从前到后挨个查询,从第一个被查询元祖到最后一个被查询元祖
被称为嵌套循环连接算法(也就是全表扫描)
eg. SC表存储学号以及上课信息,student表存储学号以及姓名信息,要求:将两个表合并到一起
方法一:
SELECT Student.*,SC*
FROM Student,SC
WHERE Student.Sno=SC.sno;
方法二:
SELSET Student.Sno,Sname,Ssex,Sage,……
FROM Student,SC
WHERE Student.Sno=SC.Sno;
根据索引找到对应的SC组,比全表扫描要快
等值连接的重复属性去掉即可称为 自然连接
1.2.2. 自身连接
一个表与自己连接,称为标的 自身连接
eg. 比如查询一门选修课的前置课程
1.2.3. 外连接
两个表连接的时候,可能会出现空值 ,这时候就需要外连接
SELECT Student.Sno……
FROM Student LEFT OUTER JOIN SC ON (Student.Sno=SC.Sno)
1.2.4. 多表连接
两个以上的表连接
SELECT Student.Sno,Sname,Cname,Grade
From Student,SC,Course
WHERE Student.Sno=SC.Sno AND SC.Cno=Course.Cno;
1.3. 嵌套查询
下面的格式称为一个 查询块
SELECT
FROM
WHERE
将一个查询块插入到另外一个查询块叫做嵌套查询
SELECT /*外层查询或父查询*/
FROM
WHERE <> IN
(
SELECT /*内层查询或子查询*/
FROM
WHERE
)
提示:子查询的SELECT不能使用ORDER BY子句;ORDER BY子句只能用在最终查询
嵌套查询使得用户可以用多个简单查询构成复杂查询
1.3.1. 带有IN的子查询
方法: 先分布来完成此查询,然后再构造嵌套查询(将第一步嵌入第二部)
不相关子查询: 子查询的查询条件不依赖于父查询
相关子查询: 子查询的查询条件依赖于父查询 此时,整个查询语句称为相关嵌套查询
数据库性能调优技术: 实现同一个查询请求可以有很多种方法
<注>:有些嵌套查询可以用运算代替,有些不可以
1.3.2. 带有比较运算符的子查询
父查询和子查询之间用比较运算符连接
SELECT Sno,Cno
FROM SC x /*x是SC的别名,又称为元组变量*/
WHERE Grade >=(SELECT AVG(Grade)
FROM SC y
WHERE y.Sno=x.Sno);
内层查询是求一个学生的平均成绩
外层查询是查询平均成绩对应的学生
参数x.Sno的值与父查询相关,所以称为 相关子查询
求解相关子查询不能像求解不相关子查询那样 一次性求解子查询在求父查询
必须反复求值
1.3.3. 带有ANY(SOME)或ALL的子查询
比较运算符 | 含义 |
---|---|
>ANY | >子查询中的某个值 |
<ANY | <子查询中的某个值 |
>=ANY | >=子查询中的某个值 |
<=ANY | <=子查询中的某个值 |
=ANY | =子查询中的某个值 |
!=ANY < >ANY | !=子查询中的某个值 |
>ALL | >子查询结果的所有值 |
<ALL | <子查询结果的所有值 |
>=ALL | >=子查询结果的所有值 |
<=ALL | <=子查询结果的所有值 |
=ALL | =子查询结果的所有值 |
!=ALL < >ALL | !=子查询结果的所有值 |
= | <> != | < | <= | > | >= | |
---|---|---|---|---|---|---|
ANY | IN | <MAX | <=MAX | >MIN | >=MIN | |
ALL | NOT IN | <MIN | <=MIN | >MAX | >=MAX |
eg. =ANY 相当于 IN
1.3.4. 带有EXISTS的子查询
EXISTS表示存在量词 存在
带有 EXISTS 的子查询不返回任何数据,只产生 “true”或“false”
SELEXT ...
FROM ..
WHERE EXISTS
(
SELECT ...
FROM ...
WHERE ...
)
若内层查询结果非空,那么外层的WHERE返回“true”,否则返回“false”
与 EXISTS 相对应的是 NOT EXISTS ,也就是,若是 NOT EXISTS ,啧内层为空值返回“true”
eg.
选择了所有的=没有一个不被选择
SQL中没有全称量词,但是可以把带有全称量词的变换为带有存在量词的语句
1.4. 集合查询
集合操作主要包括并操作UNION、交操作INTERSECT和差操作EXCEPT。
1.5. 基于派生表的查询
子查询不仅可以出现在WHERE子句中,还可以出现在FROM子句中,这是子查询生成的临时派生表称为主查询的查询对象。
SELECT Sno,Cno
FROM SC,(SELECT …… FROM SC GROUP BY Sno)
AS AVG
WHERE SC.Sno=AVG. ……
这里面FROM子句中的子查询产生一个新的派生表AVG,主查询将他们两个安学号相等进行连接
有时候AS可以省略
1.6. SELECT语句的一般格式
SELECT [ALL|DISTINCT] <目标表达式>[别名][,<目标表达式>[别名]]……
FROM <目标表达式>[别名][,<目标表达式>[别名]]…… |(<SELECT语句>)[AS]<别名>
[WHERE<条件表达式>]
[GROUP BY <列名1>[HAVING<条件表达式>]]
[GROUP BY <列名2>[ASS|DESC]]
1.6.1. 目标列 表达式 的可选格式
- *
- <表名>.*
- COUNT([DISTINCT|ALL]*)
- [<表名>.]<属性列名表达式>[,[<表名>.]<属性列名表达式>]…… 其中:<属性列明表达式>可以使自由属性列、作用于属性列的聚集函数和常量的任意算术运算(加减乘除)组成的运算公式