数据库系统概论——数据查询 MySQL实现
数据库系统概论——数据查询 & MySQL实现
查询语句
格式
SELECT [ALL | DISTINCT] <target column expression>, [<target column expression>]
FROM <table name or view name>.[<table name or view name>]
| (SELECT statement) [AS] <alias>
[WHERE <condition expression>]
[GROUP BY <column name> [HAVING <condition expression>]]
[ORDER BY <column name> [ASC | DESC]];
- SELCT
指定要显示的属性列
- FROM
指定查询对象(基本表或视图)
- WHERE
指定查询条件
- GROUP BY
对查询结果指定列的值进行分组,该属性列值相等的元素分到一个组
- HAVING
只有满足指定条件的组才予以输出
- ORDER BY
对查询结果表按指定列值升序或降序排列
查询指定列
例如,查询所有部门的名字
select dept_name from department
例如,查询表中所有列
select * from department
查询指定元组(行)
常用查询条件
查询条件 | 谓词 |
---|---|
比较 | =,<,>,>=,<=,!=,<>,!>,!<; NOT + [=,<,>,>=,<=,!=,<>,!>,!<;] |
确定范围 | BETWEEN AND, NOT BEWTEEN AND |
确定集合 | IN, NOT IN |
字符匹配 | LIKE, NOT LIKE |
空值 | IS NULL, IS NOT NULL |
多重条件(逻辑运算) | AND OR NOT |
- 比较大小
例如,查询在CS办公楼办公的部门名
select * from department where building = 'CS Building'
- 确定范围
select * from department
where budget between 1000 and 10000;
- 确定集合
select * from department where dept_name in ('CS', 'SE');
- 字符匹配
[NOT] LIKE '<match string>' [ESCAPE '<return character>']
<match string>
可以是完整字符串,也可以包含通配符%
和_
,其中%
代表任意长度的字符串,_
代表单个字符
例如,查找建筑名C
开头的部门
select * from department where building like 'C%';
- 空值
IS
不等于=
- 多重条件(逻辑运算符)
例如,查找建筑名C
开头且预算在1000和100000之间的部门
select * from department where building like 'C%' and budget between 1000 and 10000;
- ORDER BY
例如,查找所有部门并按照部门名升序排序
select * from department
order by dept_name asc;
聚集函数
统计元组个数
COUNT(*)
统计一列中值的个数
COUNT([DISTINCT | ALL] <column name>)
列求和
SUM([DISTINCT | ALL] <column name>)
列平均值
AVG([DISTINCT | ALL] <column name>)
列中最大值和最小值
MAX([DISTINCT | ALL] <column name>)
MIN([DISTINCT | ALL] <column name>)
例如
查询部门表中元组总数
select count(*) from department;
统计教职人员薪资总额
select sum(salary) from instructor;
统计教职人员薪资平均值
select avg(salary) from instructor;
查询预算最高的部门
select max(budget) from department;
GROUP BY
GROUP BY
用于细化聚集函数的作用对象,若为对查询结果分组,聚集函数将作用于整个查询结果,对查询结果分组后,聚集函数分别作用于每个组,按指定的列或多列分组,值相等的分到同一组
HAVING
HAVING
与WHERE
作用对象不同,WHERE
作用于基本表或视图,从中选择满足条件的元组,而HAVING
作用于组,从中选择满足条件的组
例如
查询教职人员数量大于1的部门
select dept_name from instructor
group by dept_name
having count(*) > 1;
查询教职工平均薪资大于10000的部门及其薪资
select dept_name, avg(salary) from instructor
group by dept_name
having avg(salary) > 10000;
连接查询
格式
[<table name>.]<column><compare operator>[<table name>.]<column name>
等值连接
例如,查询所有教职人员及其所属专业情况
select instructor.*, department.*
from instructor, department
where department.dept_name = instructor.dept_name;
自身连接
例如,查询每一门课的直接先修课名称
select FIRST.name, SECOND.name
FROM course FIRST, course SECOND
WHERE FIRST.preno = SECOND.no
外连接
例如,查询课程信息及其对应开设的专业信息
select course.*, department.*
from course left join department
on (course.dept_name = department.dept_name);
多表连接
例如,查询所有课程的ID和名字及其开设学年学期和教师名字
select course.course_id, course.title, teaches.year, teaches.semester, instructor.name
from course, teaches, instructor
where course.course_id = teaches.course_id and teaches.ID = instructor.ID;
嵌套查询
嵌套查询指的是将一个查询块嵌入到另一个查询块的WHERE
子句或HAVING
短语的条件中的查询,其中查询块指的是一个SELECT-FROM-WHERE
语句
特点
- 上层查询块称为外层查询或父查询
- 下层查询块称为内层查询或子查询
SQL
语句允许多层嵌套查询- 子查询不能使用
ORDER BY
不相关子查询
子查询的查询条件不依赖于父查询,由里向外逐层处理,每个子查询在上一级之前求解,得到的结果用于建立其父查询的查找条件
相关子查询
子查询的查询条件依赖于父查询,检查整个外层表,取外层表中的元组,根据其与内层查询相关的属性处理内层查询,将对应WHERE
子句返回值为真的元组放入结果表
IN / NOT IN 子查询
例如,查询所有在2020年第一个学期开课且不再2020第二学期开课的课程的课程ID和名称
select distinct section.course_id, course.title
from section, course
where section.semester = '1' and section.year = 2020 and
section.course_id = course.course_id and
section.course_id not in (select section.course_idfrom sectionwhere section.semester = '2' and section.year = 2020);
比较运算符子查询
例如,查询工资至少比SE系的某一教师高的所有教师的名字
select name
from instructor
where salary > some(select salaryfrom instructorwhere dept_name = 'SE');
例如,查询工资比CS系平均工资高的所有教师的名字
select name
from instructor
where salary > (select avg(salary)from instructorwhere dept_name = 'CS');
ANY / ALL谓词的子查询
ANY(SOME)
和ALL
的对象表示为某个查询结果,ANY
表示任意一个值,ALL
表示全部值,使用ANY(SOME)
和ALL
必须同时使用比较运算符,可以与聚集函数、IN
谓词等价转换
例如,查询工资比SE系的所有教师都高的所有教师的名字
select name
from instructor
where salary > all(select salaryfrom instructorwhere dept_name = 'SE');
EXISTS谓词查询
EXISTS
的对象是某个查询结果,表示其查询结果是否为空,不产生任何数据只返回真值,若内层查询结果非空,则外层的WHERE
子句返回TRUE
,否则返回FALSE
,由EXISTS
引出的子查询目标列表通常为*
,因为只返回TRUE
或FALSE
,给出列名无实际意义
例如,查询所有在CS Building
办公的教师的名字
select name
from instructor
where exists(select *from departmentwhere instructor.dept_name = department.dept_name anddepartment.building = 'CS Building');
-
可以用
EXISTS
代替所有带IN
谓词、比较运算符、ANY
和ALL
谓词的子查询 -
可以用
EXISTS/NOT EXISTS
实现全称量词 -
可以用
EXISTS
实现逻辑蕴含
例如,查询至少选修了名为Tony
选修的所有课程的学生姓名
select S2.name
from student S1
where not exists(select *from student S2, takes T2where S2.name = 'Tony' andnot exists (select *from student S3, takes T3where S3.name = S1.name andT3.ID = T2.ID)
);
其中,子查询
select *
from student S3, takes T3
where S3.name = S1.name and
T2.ID = T3.ID
找到一个学生与名为Tony
的学生选了一样的课,而子查询
where not exists(select *from student S2, takes T2where S2.name = 'Tony' andnot exists (select *from student S3, takes T3where S3.name = S1.name andT3.ID = T2.ID)
);
找出名为Tony
且不存在与Tony
选同样课的学生,NOT EXISTS
返回是否不存在名为Tony
且不存在与Tony
选同样课的学生,即若存在与Tony
选一样课的学生返回结果为TRUE
,若不存在Tony
这个学生返回结果也为TRUE
,当且仅当存在Tony
这个学生且没有人和他选一样的课返回结果为FALSE
,满足逻辑蕴含的条件
- 实现除操作
例如,查询选修了CS
系开设的所有课程的学生
select student.ID, student.name
from student
where not exists((select course_idfrom coursewhere dept_name = 'CS')except(select takes.course_idfrom takeswhere student.ID = takes.ID)
);
其中,子查询
select course_idfrom coursewhere dept_name = 'CS')
找到CS
系所有开设的课程,而子查询
select takes.course_idfrom takeswhere student.ID = takes.ID
找出当前学生选修的所有课程,若两者EXCEPT
运算得到的差集为空,则说明该学生选修了所有CS
系开设的课程,NOT EXISTS
返回TRUE
集合查询
并操作
select * from department
union
select * from department0;
交操作
select * from department
inner join department0 on department.building = department0.building;
差操作
- NOT IN
select * from department
where building not in
(select building from department0);
- LEFT JOIN
select * from department
left join department0 on department.building = department0.building
where department0.building is null;
鸣谢
数据库系统概论(第5版)
数据库系统概念(原书第6版)
最后
- 由于博主水平有限,不免有疏漏之处,欢迎读者随时批评指正,以免造成不必要的误解
发布评论