【MySQL】数据库的高级查询

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 上次我们讲了数据库的基本查询,这次继续接上来数据库的高级查询。高级查询是建立在基础查询的基础上面的,如果你还没有看过建议你先去学习数据库的基础查询。

前言


上次我们讲了数据库的基本查询,这次继续接上来数据库的高级查询。高级查询是建立在基础查询的基础上面的,如果你还没有看过建议你先去学习数据库的基础查询。


数据库的查询是数据库学习部分的重点,而数据库的高级查询是更加的重要,大家要注意多多练习,才可以更好的掌握。


建表

在基本查询中我们已经,建过表了,但是数据库的高级查询部分涉及到多个表的查询所以,我们还需要再建表,方便我们在学习过程中更好的理解记忆。


我们先建立学生表

create  table t_student(
  id  INT PRIMARY KEY NOT NULL,
  name  VARCHAR(4) NOT NULL,
  age   INT NOT NULL,
  sex   CHAR(1) NOT NULL,
  class VARCHAR(10) ,
  birthplace  varchar(10),
  id_teach INT UNSIGNED NOT NULL
);
#DROP TABLE t_student;
INSERT INTO t_student VALUES('88201','张三',18,'男','软件211','浙江杭州',689);
INSERT INTO t_student VALUES('88202','李四',19,'男','软件212','河南郑州',898);
INSERT INTO t_student VALUES('88203','小红',18,'女','计算机211','北京',758);
INSERT INTO t_student VALUES('88204','王五',16,'男','软件214','浙江杭州',589);
INSERT INTO t_student VALUES('88205','小蓝',17,'女','计算机212','江苏常州',988);
INSERT INTO t_student VALUES('88206','小王',20,'男','软件211','北京',689);
INSERT INTO t_student VALUES('88207','张四',18,'男','计算机211','江苏常州',758);


输出:

image.png

建立老师表

CREATE TABLE t_teach(
  id INT PRIMARY KEY NOT NULL,
  name VARCHAR(10) NOT NULL,
  age INT ,
  sex  CHAR(1) ,
  birthplace  varchar(10)
);



输出:

image.png

建立成绩表:

CREATE TABLE t_grade(
  id  INT PRIMARY KEY NOT NULL,
  chinese INT UNSIGNED,
  english INT UNSIGNED,
  java INT UNSIGNED,
  python INT UNSIGNED
);



输出:

image.png

建表完成,这三张表都具有一定的关联性,我们就使用这三张表来学习MySQL数据库的高级查询部分。


聚合函数

聚合函数是MySQL数据库数据处理过程中经常会用到的,求最小值、最大值、求和等。


MySQL数据库常用聚合函数详解如下:


AVG(col):返回指定列的平均值

COUNT(col):返回指定列中非NULL值的个数

MIN(col):返回指定列的最小值

MAX(col):返回指定列的最大值

SUM(col): 返回指定列的所有值之和

GROUP_CONCAT:返回由属于一组的列值连接组合而成的结果


使用格式:

SELECT COUNT(字段名) FROM 表名;
SELECT MAX(字段名) FROM 表名; 
SELECT MIN(字段名) FROM 表名;
SELECT SUM(字段名) FROM 表名;


示例:全班总分数最高的人是谁?


SELECT id,MAX(chinese+english+java+python) AS count_grade

FROM t_grade;


输出:

image.png


分组查询

GROUP BY 是分组,分组并不是去重,将查询结果按一个或多个进行分组,字段值相同的为同一组


格式如下:


SELECT  字段名1,字段名2,… FROM 表名 GROUP BY 字段1,字段2,..


GROUP BY后面的字段就是分组依据的字段,先按照字段1分组,然后按照字段二再次分组以此类推…


示例:按照班级分组


SELECT class,GROUP_CONCAT(name)

FROM t_student GROUP BY class;


输出:

image.png


Having子句

HAVING子句通常与GROUP BY子句一起使用,在SELECT语句中使用HAVING子句来指定一组行或聚合的过滤条件,以根据指定的条件过滤分组。


如果省略GROUP BY子句,则HAVING子句的行为与WHERE子句类似。但是,HAVING字句可以让我们筛选分组之后的各种数据。WHERE子句在聚合前先筛选记录,也就是说作用在GROUP BY和HAVING字句前。而HAVING子句在聚合后对组记录进行筛选。我的理解就是真实表中没有此数据,这些数据是通过一些函数产生的。


也就是说HAVING子句与WHERE子句都是可以进行条件查询的,但是WHERE子句中的条件不能包括聚合函数,但是HAVING子句可以。


这时候可能有人要说了,既然他们两个都是可以进行条件查询的,而且HAVING子句功能比WHERE子句的功能强大,那么我们为什么还要学习WHERE子句呢?


这里要注意的WHERE子句执行在SELECT子句前面,HAVING子句执行在SELECT子句的后面,如果我们使用WHERE子句的话就可以先筛选掉一大部分的数据,这要查询速度比较快,而如果只用HAVING子句那么查询速度比较慢,这样就不是一个最优的查询程序了。


使用格式如下:


SELECT 字段名1,字段名2,…

FROM 表名

GROUP BY 字段

HAVING 筛选条件;


示例:平均年龄不低于18的班级

SELECT class,GROUP_CONCAT(name)
FROM t_student 
GROUP BY class
HAVING AVG(age)>=18;


输出;


image.png

表连接查询

我们在进行数据查询时候,往往需要的数据在不同的表上,这时候我们就需要把表连接在一起来进行多表查询。表连接查询又分为:内连接查询,外连接查询,自然连接查询


接下来,我们对它们依次进行学习

image.png

内连接查询

内连接是通过在查询中设置连接条件的方式,来移除查询结果集中某些数据行后的交叉连接。简单来说,就是利用条件表达式来消除交叉连接的某些数据行。


在MySQL 的FROM 子句中使用关键字 INNER JOIN 或 JOIN 连接两张表,并使用 ON 子句来设置连接条件。内连接是系统默认的表连接,所以在 FROM 子句后可以省略 INNER 关键字,只用关键字 JOIN。使用内连接后,FROM 子句中的 ON 子句可用来设置连接表的条件。


连接格式:

SELECT 字段名1,字段名2,…
FROM 表名1 JOIN 表名2...
ON 连接条件;



示例:

SELECT * 
FROM t_student AS s JOIN t_teach AS t 
ON s.id_teach=t.id;



输出:

image.png

内连接还有一种隐式写法:


SELECT 字段名1,字段名2,…

FROM 表名1,表名2...

WHILE 连接条件;


效果都是一样的,不过写的时候容易忘记条件,不推荐使用这种。


外连接查询

外连接查询又分为:左连接查询与右连接查询。其中左连接查询是指以左边的表为主表,以主表的数据为基准,去匹配右边的表的数据,如果匹配到就显示,匹配不到就显示为NULL;右连接查询类似。


左外联接查询LEFT OUTER JOIN,MySQL中可以简写为LEFT JOIN;

右外联接查询RIGHT OUTER JOIN,MySQL可以简写为RIGHT JOIN;


SELECT 字段名1,字段名2,…

FROM 表名1 LEFT|RIGHT JOIN 表名2...

ON 连接条件;


示例:

SELECT * 
FROM t_student AS s LEFT JOIN t_teach AS t 
ON s.id_teach=t.id;



输出:

image.png

示例:

SELECT * 
FROM t_student AS s RIGHT JOIN t_teach AS t 
ON s.id_teach=t.id;



输出:

image.png

这里在介绍一个关键字UNION,它可以把多条SQL语句的查询结果,合并成一个结果集。如下:

SELECT * 
FROM t_student AS s JOIN t_teach AS t 
ON s.id_teach=t.id
UNION
SELECT * 
FROM t_student AS s RIGHT JOIN t_teach AS t 
ON s.id_teach=t.id;


输出:

image.png


自然连接查询

自连接查询就是当前表与自身的连接查询,关键点在于虚拟化出一张表给一个别名,自连接查询一般用作表中的某个字段的值是引用另一个字段的值。

示例:

SELECT t1.id,t1.java
FROM t_grade AS t1 JOIN t_grade AS t2
ON t1.java=t2.java
HAVING t1.java>=AVG(t2.java);


输出:

image.png


子查询

子查询允许把一个查询嵌套在另一个查询当中。子查询,又叫内部查询,相对于内部查询,包含内部查询的就称为外部查询。子查询可以包含普通SELECT可以包括的任何子句,它嵌套在一个 SELECT、SELECT…INTO 语句、INSERT…INTO 语句、DELETE 语句、或 UPDATE 语句或嵌套在另一子查询中。


在 SELECT 子句中先计算子查询,子查询结果作为外层另一个查询的过滤条件,查询可以基于一个表或者多个表。


子查询中常用的运算符

IN子查询

结合关键字 IN 所使用的子查询主要用于判断一个给定值是否存在于子查询的结果集中。其语法格式为:


<表达式> [NOT] IN <子查询>


语法说明如下。

<表达式>:用于指定表达式。当表达式与子查询返回的结果集中的某个值相等时,返回 TRUE,否则返FALSE;若使用关键字 NOT,则返回的值正好相反。


<子查询>:用于指定子查询。这里的子查询只能返回一列数据。对于比较复杂的查询要求,可以使用 SELECT 语句实现子查询的多层嵌套。


比较运算符子查询


比较运算符所使用的子查询主要用于对表达式的值和子查询返回的值进行比较运算。其语法格式为:


<表达式> {= | < | > | >= | <= | <=> | < > | != }

[ ALL | SOME | ANY]<子查询>


语法说明如下。

<子查询>:用于指定子查询。

<表达式>:用于指定要进行比较的表达式。

ALL、SOME 和 ANY:可选项,用于指定对比较运算的限制。


关键字 ALL 用于指定表达式需要与子查询结果集中的每个值都进行比较,当表达式与每个值都满足比较关系时,会返回 TRUE,否则返回 FALSE;

关键字 SOME 和 ANY 是同义词,表示表达式只要与子查询结果集中的某个值满足比较关系,就返回 TRUE,否则返回 FALSE。

EXIST子查询


关键字 EXIST 所使用的子查询主要用于判断子查询的结果集是否为空。其语法格式为:


EXIST <子查询>


若子查询的结果集不为空,则返回 TRUE;否则返回 FALSE。


子查询分类

子查询有以下几种:


1.标量子查询:返回单一值的标量,最简单的形式。

2.列子查询:返回的结果集是 N 行一列。

3.行子查询:返回的结果集是一行 N 列。

4.表子查询:返回的结果集是 N 行 N 列。


标量子查询:是指子查询返回的是单一值的标量,如一个数字或一个字符串,也是子查询中最简单的返回形式。 可以使用 = > < >= <= <> 这些操作符对子查询的标量结果进行比较,通常子查询的位置在比较式的右侧


MySQL 列子查询:指子查询返回的结果集是 N 行一列,由于列子查询返回的结果集是 N 行一列,因此不能直接使用 = > < >= <= <> 这些比较标量结果的操作符。在列子查询中可以使用 IN、ANY、SOME 和 ALL 操作符


MySQL 行子查询:行子查询是指子查询返回的结果集是一行 N 列,该子查询的结果通常是对表的某行数据进行查询而返回的结果集,同理不能直接使用 = > < >= <= <> 这些比较标量结果的操作符。


MySQL 表子查询:指子查询返回的结果集是 N 行 N 列的一个表数据,同理不能直接使用 = > < >= <= <> 这些比较标量结果的操作符。


示例:老师来自北京的学生有哪些?

SELECT id,name
FROM t_student
WHERE id_teach=
(SELECT id
FROM t_teach
WHERE birthplace="北京");


输出:

image.png

示例:有哪些学生与老师的出生地相同?

SELECT id,name,birthplace
FROM t_student
WHERE birthplace = ANY
(SELECT birthplace
FROM t_teach);



输出:


image.png

结语

MySQL数据库这一部分我们的讲解就到此为止了,但是学习并没有结束,我们得不断地进行练习,只有这样我们在以后的工作中才能熟练的运用它们来进行办公!



相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
2天前
|
SQL 前端开发 关系型数据库
SpringBoot使用mysql查询昨天、今天、过去一周、过去半年、过去一年数据
SpringBoot使用mysql查询昨天、今天、过去一周、过去半年、过去一年数据
29 9
|
4天前
|
缓存 监控 关系型数据库
如何优化MySQL查询速度?
如何优化MySQL查询速度?【10月更文挑战第31天】
15 3
|
6天前
|
存储 缓存 固态存储
怎么让数据库查询更快
【10月更文挑战第28天】
14 2
|
8天前
|
存储 缓存 关系型数据库
怎么让数据库查询更快
【10月更文挑战第25天】通过以上综合的方法,可以有效地提高数据库查询的速度,提升应用程序的性能和响应速度。但在优化过程中,需要根据具体的数据库系统、应用场景和数据特点进行合理的调整和测试,以找到最适合的优化方案。
|
8天前
|
监控 关系型数据库 MySQL
数据库优化:MySQL索引策略与查询性能调优实战
【10月更文挑战第27天】本文深入探讨了MySQL的索引策略和查询性能调优技巧。通过介绍B-Tree索引、哈希索引和全文索引等不同类型,以及如何创建和维护索引,结合实战案例分析查询执行计划,帮助读者掌握提升查询性能的方法。定期优化索引和调整查询语句是提高数据库性能的关键。
41 0
|
9天前
|
监控 关系型数据库 MySQL
数据库优化:MySQL索引策略与查询性能调优实战
【10月更文挑战第26天】数据库作为现代应用系统的核心组件,其性能优化至关重要。本文主要探讨MySQL的索引策略与查询性能调优。通过合理创建索引(如B-Tree、复合索引)和优化查询语句(如使用EXPLAIN、优化分页查询),可以显著提升数据库的响应速度和稳定性。实践中还需定期审查慢查询日志,持续优化性能。
36 0
|
27天前
|
存储 SQL 关系型数据库
Mysql学习笔记(二):数据库命令行代码总结
这篇文章是关于MySQL数据库命令行操作的总结,包括登录、退出、查看时间与版本、数据库和数据表的基本操作(如创建、删除、查看)、数据的增删改查等。它还涉及了如何通过SQL语句进行条件查询、模糊查询、范围查询和限制查询,以及如何进行表结构的修改。这些内容对于初学者来说非常实用,是学习MySQL数据库管理的基础。
104 6
|
25天前
|
存储 关系型数据库 MySQL
Mysql(4)—数据库索引
数据库索引是用于提高数据检索效率的数据结构,类似于书籍中的索引。它允许用户快速找到数据,而无需扫描整个表。MySQL中的索引可以显著提升查询速度,使数据库操作更加高效。索引的发展经历了从无索引、简单索引到B-树、哈希索引、位图索引、全文索引等多个阶段。
57 3
Mysql(4)—数据库索引
|
27天前
|
SQL Ubuntu 关系型数据库
Mysql学习笔记(一):数据库详细介绍以及Navicat简单使用
本文为MySQL学习笔记,介绍了数据库的基本概念,包括行、列、主键等,并解释了C/S和B/S架构以及SQL语言的分类。接着,指导如何在Windows和Ubuntu系统上安装MySQL,并提供了启动、停止和重启服务的命令。文章还涵盖了Navicat的使用,包括安装、登录和新建表格等步骤。最后,介绍了MySQL中的数据类型和字段约束,如主键、外键、非空和唯一等。
62 3
Mysql学习笔记(一):数据库详细介绍以及Navicat简单使用
|
10天前
|
关系型数据库 MySQL Linux
在 CentOS 7 中通过编译源码方式安装 MySQL 数据库的详细步骤,包括准备工作、下载源码、编译安装、配置 MySQL 服务、登录设置等。
本文介绍了在 CentOS 7 中通过编译源码方式安装 MySQL 数据库的详细步骤,包括准备工作、下载源码、编译安装、配置 MySQL 服务、登录设置等。同时,文章还对比了编译源码安装与使用 RPM 包安装的优缺点,帮助读者根据需求选择最合适的方法。通过具体案例,展示了编译源码安装的灵活性和定制性。
46 2