# 单表查询
# 选择表中的若干列
相当于关系运算中的投影
查询指定列
select 列
from 表名;
2
查询全部列
select *
from 表名;
2
查询经过计算的列
select 包含属性的表达式
from 表名;
2
为查询后的列更名
select 原名 别名, 原名 别名
from 表名;
2
# 选择表中的若干元组
清除取值重复的行
关系要求其中的每一个都是唯一的,但两个本来不同的元组在投影后,可能会产生相同的结果。此时可以使用 distinct 清除重复部分
select distinct 列
from 表名;
2
查询满足条件的元组
select 列
from 表名
where 条件;
2
3
可以和 distinct 配合使用,符合条件的元组只会出现一次
常用查询条件
- 比较
例如:
select name, wages from payroll where wages > 10000;
1
2
3
- 确定范围
where 属性 (not) between 数组下限 and 数值上限
例如:
select name, wages from payroll where wages between 1000 and 10000;
1
2
3
- 确定集合
where 属性 (not) in (属性集合)
例如:
select num, color from ball where color in ('red', 'black');
1
2
3
- 字符匹配 like 可以用于进行字符串的匹配,其一般格式为:
where 属性 (not) like '匹配串'
寻找指定属性列中与匹配串相匹配的元组。
匹配串可以是一个字符串,也可以包含通配符。
通配符:
- %:代表任意长度(可以为零)的字符串
- _:代表任意单个字符
例如:
select num, color from ball where name like '%x_';
1
2
3则,
aaaxb
、xc
等都会被筛选出来。如果 like 后面的匹配串中不含通配符,可以用 = 替代
若匹配串中本身自带了 %及 _ 字符,可以用 escape 对其进行转义
例如:
where Cname like 'A\_B' eacape '\'
1这段代码的意思是将 \ 设为转义字符,跟在 \ 后面的通配符将被转义为普通字符。此时会寻找对应属性等价于 ‘A_B’ 的元组
查询空值
where 属性 is null
此处的
is
不能够用=
替代。因为 “是空的” ,而不是 “等于空”
- 多重条件查询
可以通过 and 、or 、not 连接多个条件,进行复杂的查询。
in 可以看作是多个 or 的语法糖。
where name in ('zhang', 'li')
1等价于
where name = 'zhang' or name = 'li'
1
# order by
用户可以通过 order by
对查询结果按照一个或多个属性列进行升序 (asc) 或降序 (desc) 排列。(默认为升序)
select 列名
from 表名
order by 排序元组 asc|desc;
2
3
# 聚集函数
输入值的集合,返回单个值的函数
count
count(*)
统计元组个数
count(distinct|all 列名)
统计一列中值的个数
sum
sum(distinct|all 列名)
avg
avg(distinct|all 列名)
max
max(distinct|all 列名)
min
min(distinct|all 列名)
注意
- 若指定了 distinct ,则会在计算时取消重复值;若没有指定,则默认为 all ,在计算时不取消重复值
- 当聚集函数遇到空值时,除了
count(*)
以外,都会跳过空值 - 聚集函数不能用于 where 语句,仅能用于 select 和 group by 中的 having
# group by
作用
该语句将查询结果按值分组,需要配合聚集函数使用。
常用用法:
- 首先按照属性的不同将表分为若干组
select 聚焦函数
,算出每一组的函数值select 分组字段
用于对聚集函数的结果进行标识也可以
select 普通字段
,会自动将分组中第一条记录的对应值作为结果中的值,但这没有任何意义
基本语法
select 属性, 聚集函数
from 表名
group by 属性;
2
3
运行结果
属性1 聚焦函数(分组1)
属性2 聚焦函数(分组2)
属性3 聚焦函数(分组3)
2
3
having
分组后可以用 having 语句指定筛选条件,满足条件的分组才会被选出来。
where:用于筛选元组,在分组前进行限定
having:用于筛选元组组成的分组,在分组后对分组进行限定
select 属性, 聚集函数
from 表名
group by 属性
having 筛选条件;
2
3
4
示例
数据表:
查询语句:
SELECT
sex,
AVG( score )
FROM
students
GROUP BY
sex
2
3
4
5
6
7
查询结果:
# 连接查询
若一个查询同时两个以上的表,则称为连接查询,包括等值连接查询、自然连接查询、非等值连接查询、自身连接查询、外连接查询和复合条件连接查询等。
# 等值和非等值连接
where [表名1].列名1 = [表名2].列名2
- where 语句中用来连接两个表的条件称为连接条件,连接条件中的运算符称为连接运算符。
- 当连接运算符为 = 时,称为等值连接;使用其它运算符时称为非等值连接。
- 连接条件中的两边必须具有可比性。
- 可以在属性名前面加上表名前缀,防止产生混淆
例如:
将学生和课程进行等值连接查询,组成选课情况表。select Student.*, SC.* from Student, SC where Student.Sno = SC.Sno;
1
2
3
# 自然连接
在等值连接中,把目标列中重复的属性列去掉,就是自然连接。
等值连接:选择两个关系中对应属性相等的元组,拼在一起
自然连接:对等值连接结果做一次投影,相同的属性只保留一份
# 自身连接
一个表与自身的连接,称为自身连接。
例如:
要将同一个表连接起来,首先应该为两个表分别起一个别名,然后进行连接。select First.Cno, SECOND.Cpno from Course First, Course SECOND where FIRST.Cpno = SECOND.Cno;
1
2
3
# 外连接
将两个表进行连接操作时,在另外一个表中没有对应元组的元组也加入到查询结果中,空缺的部分用 null 填补。若保留左边,则称为左外连接;保留右边,则称为右外连接。
例如:
select Student.Sno, Sname, Ssex, Sage, Cno, Grade form Student left outer join SC on (Student.Sno = SC.Sno)
1
2
# 多表连接
连接操作还可以同时连接多个表。
# 嵌套查询
在 SQL 语言中,一个 select - from - where
称为一个查询块。将一个查询块嵌套在另一个查询块的 where 或 having 中的查询称为 嵌套查询。
例如:
select Sname from Student where Sno in (select Sno from SC where Cno = '2');
1
2
3
4
5
6在此例中,上层查询块被称为外层查询或父查询,下层查询块被称为内层查询或子查询。
- SQL 语言允许多层嵌套查询,即一个子查询中还可以嵌套其它子查询。
- 子查询中不能使用 order by ,因为对非最终结果的排序是无意义的
- 嵌套查询使用户能够用多个简单查询构成复杂的查询
# 筛选-判断是否在集合中
如果子查询的结果是一个集合,那么可以用 in 或 not in 筛选元组。
# 筛选-与值比较
当用户明确知道子查询返回的是单个值时,可以用 > 、< 、= 等比较运算符。
# 筛选-与集合比较
若子查询返回集合,且需要进行比较查询,便可以使用 any 和 all 。其中, any 指任意, all 指所有。
# 用 exists 判断是否存在
带有 exists 的子查询不返回任何数据,只返回 true 和 false 。
例如:
由 exists 引出的子循环,其目标列表达式通常都用 * ,因为查询只返回布尔值,给出列名无实际意义。
# 集合查询
即通过“并 union ”、“交 intersect ”和“差 except ”,对多个 select 的结果进行集合运算。
select-from-where union|intersect|except select-from-where;
# 基于派生表的查询
子查询不仅可以出现在 where 中,也可以出现在 from 中,此时子查询会生成临时派生表,作为主查询的查询对象。
需要注意,基于派生表的查询需要为派生表指定别名。