# 单表查询

# 选择表中的若干列

相当于关系运算中的投影

查询指定列

select 列
from 表名;
1
2

查询全部列

select *
from 表名;
1
2

查询经过计算的列

select 包含属性的表达式
from 表名;
1
2

为查询后的列更名

select 原名 别名, 原名 别名
from 表名;
1
2

# 选择表中的若干元组

清除取值重复的行

关系要求其中的每一个都是唯一的,但两个本来不同的元组在投影后,可能会产生相同的结果。此时可以使用 distinct 清除重复部分

select distinct 列
from 表名;
1
2

查询满足条件的元组

select 列
from 表名
where 条件;
1
2
3

可以和 distinct 配合使用,符合条件的元组只会出现一次

常用查询条件

  • 比较

例如:

select name, wages
from payroll
where wages > 10000;
1
2
3
  • 确定范围
where 属性 (not) between 数组下限 and 数值上限
1

例如:

select name, wages
from payroll
where wages between 1000 and 10000;
1
2
3
  • 确定集合
where 属性 (not) in (属性集合)
1

例如:

select num, color
from ball
where color in ('red', 'black');
1
2
3
  • 字符匹配 like 可以用于进行字符串的匹配,其一般格式为:
where 属性 (not) like '匹配串'
1
  • 寻找指定属性列中与匹配串相匹配的元组。

  • 匹配串可以是一个字符串,也可以包含通配符。

  • 通配符:

    • %:代表任意长度(可以为零)的字符串
    • _:代表任意单个字符

    例如:

    select num, color
    from ball
    where name like '%x_';
    
    1
    2
    3

    则,aaaxbxc 等都会被筛选出来。

  • 如果 like 后面的匹配串中不含通配符,可以用 = 替代

  • 若匹配串中本身自带了 %及 _ 字符,可以用 escape 对其进行转义

    例如:

    where Cname like 'A\_B' eacape '\'
    
    1

    这段代码的意思是将 \ 设为转义字符,跟在 \ 后面的通配符将被转义为普通字符。此时会寻找对应属性等价于 ‘A_B’ 的元组

  • 查询空值

where 属性 is null
1

此处的 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;
1
2
3

# 聚集函数

输入值的集合,返回单个值的函数

count

count(*)
1

统计元组个数

count(distinct|all 列名)
1

统计一列中值的个数
sum

sum(distinct|all 列名)
1

avg

avg(distinct|all 列名)
1

max

max(distinct|all 列名)
1

min

min(distinct|all 列名)
1

注意

  • 若指定了 distinct ,则会在计算时取消重复值;若没有指定,则默认为 all ,在计算时不取消重复值
  • 当聚集函数遇到空值时,除了 count(*) 以外,都会跳过空值
  • 聚集函数不能用于 where 语句,仅能用于 select 和 group by 中的 having

# group by

作用
该语句将查询结果按值分组,需要配合聚集函数使用。
常用用法:

  • 首先按照属性的不同将表分为若干组
  • select 聚焦函数,算出每一组的函数值
  • select 分组字段 用于对聚集函数的结果进行标识

    也可以 select 普通字段 ,会自动将分组中第一条记录的对应值作为结果中的值,但这没有任何意义

基本语法

select 属性, 聚集函数
from 表名
group by 属性;
1
2
3

运行结果

属性1  聚焦函数(分组1)
属性2  聚焦函数(分组2)
属性3  聚焦函数(分组3)
1
2
3

having
分组后可以用 having 语句指定筛选条件,满足条件的分组才会被选出来。

where:用于筛选元组,在分组前进行限定
having:用于筛选元组组成的分组,在分组后对分组进行限定

select 属性, 聚集函数
from 表名
group by 属性
having 筛选条件;
1
2
3
4

示例
数据表:

查询语句:

SELECT
	sex,
	AVG( score ) 
FROM
	students 
GROUP BY
	sex
1
2
3
4
5
6
7

查询结果:

# 连接查询

若一个查询同时两个以上的表,则称为连接查询,包括等值连接查询、自然连接查询、非等值连接查询、自身连接查询、外连接查询和复合条件连接查询等。

# 等值和非等值连接

where [表名1].列名1 = [表名2].列名2
1
  • 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;
1

# 基于派生表的查询

子查询不仅可以出现在 where 中,也可以出现在 from 中,此时子查询会生成临时派生表,作为主查询的查询对象。
需要注意,基于派生表的查询需要为派生表指定别名。