【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
相关文章
|
4天前
|
NoSQL 关系型数据库 MySQL
微服务架构下的数据库选择:MySQL、PostgreSQL 还是 NoSQL?
在微服务架构中,数据库的选择至关重要。不同类型的数据库适用于不同的需求和场景。在本文章中,我们将深入探讨传统的关系型数据库(如 MySQL 和 PostgreSQL)与现代 NoSQL 数据库的优劣势,并分析在微服务架构下的最佳实践。
|
6天前
|
存储 SQL 关系型数据库
使用MySQL Workbench进行数据库备份
【9月更文挑战第13天】以下是使用MySQL Workbench进行数据库备份的步骤:启动软件后,通过“Database”菜单中的“管理连接”选项配置并选择要备份的数据库。随后,选择“数据导出”,确认导出的数据库及格式(推荐SQL格式),设置存储路径,点击“开始导出”。完成后,可在指定路径找到备份文件,建议定期备份并存储于安全位置。
66 11
|
1天前
|
存储 SQL 关系型数据库
MySQL的安装&数据库的简单操作
本文介绍了数据库的基本概念及MySQL的安装配置。首先解释了数据库、数据库管理系统和SQL的概念,接着详细描述了MySQL的安装步骤及其全局配置文件my.ini的调整方法。文章还介绍了如何启动MySQL服务,包括配置环境变量和使用命令行的方法。最后,详细说明了数据库的各种操作,如创建、选择和删除数据库的SQL语句,并提供了实际操作示例。
25 13
MySQL的安装&数据库的简单操作
|
7天前
|
存储 SQL 关系型数据库
一篇文章搞懂MySQL的分库分表,从拆分场景、目标评估、拆分方案、不停机迁移、一致性补偿等方面详细阐述MySQL数据库的分库分表方案
MySQL如何进行分库分表、数据迁移?从相关概念、使用场景、拆分方式、分表字段选择、数据一致性校验等角度阐述MySQL数据库的分库分表方案。
一篇文章搞懂MySQL的分库分表,从拆分场景、目标评估、拆分方案、不停机迁移、一致性补偿等方面详细阐述MySQL数据库的分库分表方案
|
3天前
|
存储 缓存 关系型数据库
MySQL 查询优化方法
在数据库应用中,高效的查询性能至关重要。本文探讨了常用的 MySQL 查询优化方法,包括索引优化(选择合适的索引字段、复合索引、定期维护索引)、查询语句优化(避免全表扫描、限制返回行数、避免使用不必要的函数)、表结构优化(选择合适的数据类型、分区表、定期清理无用数据)及数据库配置优化(调整缓存大小、优化存储引擎参数)。通过这些方法,可以显著提高 MySQL 的查询性能,为应用程序提供更好的用户体验。
|
5天前
|
SQL 监控 关系型数据库
MySQL数据库中如何检查一条SQL语句是否被回滚
检查MySQL中的SQL语句是否被回滚需要综合使用日志分析、事务状态监控和事务控制语句。理解和应用这些工具和命令,可以有效地管理和验证数据库事务的执行情况,确保数据的一致性和系统的稳定性。此外,熟悉事务的ACID属性和正确设置事务隔离级别对于预防数据问题和解决事务冲突同样重要。
18 2
|
30天前
|
SQL 关系型数据库 MySQL
【揭秘】MySQL binlog日志与GTID:如何让数据库备份恢复变得轻松简单?
【8月更文挑战第22天】MySQL的binlog日志记录数据变更,用于恢复、复制和点恢复;GTID为每笔事务分配唯一ID,简化复制和恢复流程。开启binlog和GTID后,可通过`mysqldump`进行逻辑备份,包含binlog位置信息,或用`xtrabackup`做物理备份。恢复时,使用`mysql`命令执行备份文件,或通过`innobackupex`恢复物理备份。GTID模式下的主从复制配置更简便。
124 2
|
25天前
|
弹性计算 关系型数据库 数据库
手把手带你从自建 MySQL 迁移到云数据库,一步就能脱胎换骨
阿里云瑶池数据库来开课啦!自建数据库迁移至云数据库 RDS原来只要一步操作就能搞定!点击阅读原文完成实验就可获得一本日历哦~
|
28天前
|
关系型数据库 MySQL 数据库
RDS MySQL灾备服务协同解决方案构建问题之数据库备份数据的云上云下迁移如何解决
RDS MySQL灾备服务协同解决方案构建问题之数据库备份数据的云上云下迁移如何解决
|
25天前
|
人工智能 小程序 关系型数据库
【MySQL】黑悟空都掌握的技能,数据库隔离级别全攻略
本文以热门游戏《黑神话:悟空》为契机,深入浅出地解析了数据库事务的四种隔离级别:读未提交、读已提交、可重复读和串行化。通过具体示例,展示了不同隔离级别下的事务行为差异及可能遇到的问题,如脏读、不可重复读和幻读等。此外,还介绍了在MySQL中设置隔离级别的方法,包括全局和会话级别的调整,并通过实操演示了各隔离级别下的具体效果。本文旨在帮助开发者更好地理解和运用事务隔离级别,以提升数据库应用的一致性和性能。
104 2
【MySQL】黑悟空都掌握的技能,数据库隔离级别全攻略