数据库系统概论——数据查询 & 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

HAVINGWHERE作用对象不同,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_id
                    from section
                    where section.semester = '2' and section.year = 2020);

比较运算符子查询

例如,查询工资至少比SE系的某一教师高的所有教师的名字

select name
from instructor
where salary > some(select salary
                    from instructor
                    where dept_name = 'SE');

例如,查询工资比CS系平均工资高的所有教师的名字

select name
from instructor
where salary > (select avg(salary)
                    from instructor
                    where dept_name = 'CS');

ANY / ALL谓词的子查询

ANY(SOME)ALL的对象表示为某个查询结果,ANY表示任意一个值,ALL表示全部值,使用ANY(SOME)ALL必须同时使用比较运算符,可以与聚集函数、IN谓词等价转换

例如,查询工资比SE系的所有教师都高的所有教师的名字

select name
from instructor
where salary > all(select salary
                    from instructor
                    where dept_name = 'SE');

EXISTS谓词查询

EXISTS的对象是某个查询结果,表示其查询结果是否为空,不产生任何数据只返回真值,若内层查询结果非空,则外层的WHERE子句返回TRUE,否则返回FALSE,由EXISTS引出的子查询目标列表通常为*,因为只返回TRUEFALSE,给出列名无实际意义

例如,查询所有在CS Building办公的教师的名字

select name
from instructor
where exists(select *
            from department
            where instructor.dept_name = department.dept_name and
            department.building = 'CS Building');
  • 可以用EXISTS代替所有带IN谓词、比较运算符、ANYALL谓词的子查询

  • 可以用EXISTS/NOT EXISTS实现全称量词

  • 可以用EXISTS实现逻辑蕴含

例如,查询至少选修了名为Tony选修的所有课程的学生姓名

select S2.name
from student S1
where not exists(
    select *
    from student S2, takes T2
    where S2.name = 'Tony' and
    not exists (
        select *
        from student S3, takes T3
        where S3.name = S1.name and
        T3.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 T2
    where S2.name = 'Tony' and
    not exists (
        select *
        from student S3, takes T3
        where S3.name = S1.name and
        T3.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_id
    from course
    where dept_name = 'CS')
    except
    (select takes.course_id
    from takes
    where student.ID = takes.ID)
);

其中,子查询

select course_id
  from course
  where dept_name = 'CS')

找到CS系所有开设的课程,而子查询

select takes.course_id
    from takes
    where 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版)

最后

  • 由于博主水平有限,不免有疏漏之处,欢迎读者随时批评指正,以免造成不必要的误解

猜你喜欢

转载自blog.csdn.net/qq_44486439/article/details/107902804