【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
相关文章
|
23天前
|
缓存 关系型数据库 MySQL
MySQL索引策略与查询性能调优实战
在实际应用中,需要根据具体的业务需求和查询模式,综合运用索引策略和查询性能调优方法,不断地测试和优化,以提高MySQL数据库的查询性能。
|
3天前
|
关系型数据库 MySQL 数据库
Python处理数据库:MySQL与SQLite详解 | python小知识
本文详细介绍了如何使用Python操作MySQL和SQLite数据库,包括安装必要的库、连接数据库、执行增删改查等基本操作,适合初学者快速上手。
45 15
|
3天前
|
关系型数据库 MySQL 数据库
数据库数据恢复—MYSQL数据库文件损坏的数据恢复案例
mysql数据库文件ibdata1、MYI、MYD损坏。 故障表现:1、数据库无法进行查询等操作;2、使用mysqlcheck和myisamchk无法修复数据库。
|
8天前
|
存储 缓存 网络协议
数据库执行查询请求的过程?
客户端发起TCP连接请求,服务端通过连接器验证主机信息、用户名及密码,验证通过后创建专用进程处理交互。服务端进程缓存以减少创建和销毁线程的开销。后续步骤包括缓存查询(8.0版后移除)、语法解析、查询优化及存储引擎调用,最终返回查询结果。
19 6
|
7天前
|
SQL 关系型数据库 MySQL
MySQL导入.sql文件后数据库乱码问题
本文分析了导入.sql文件后数据库备注出现乱码的原因,包括字符集不匹配、备注内容编码问题及MySQL版本或配置问题,并提供了详细的解决步骤,如检查和统一字符集设置、修改客户端连接方式、检查MySQL配置等,确保导入过程顺利。
|
15天前
|
关系型数据库 MySQL 数据库
GBase 数据库如何像MYSQL一样存放多行数据
GBase 数据库如何像MYSQL一样存放多行数据
|
6天前
|
SQL JavaScript 程序员
数据库LIKE查询屡试不爽?揭秘大多数人都忽视的秘密操作符!
本文分析了因数据库中的不可见空白字符导致的数据查询问题,探讨了问题的成因与特性,并提出了使用 SQL 语句修复问题的有效方案。同时,总结了避免类似问题的经验和注意事项。
18 0
|
13天前
|
JSON JavaScript 关系型数据库
node.js连接GBase 8a 数据库 并进行查询代码示例
node.js连接GBase 8a 数据库 并进行查询代码示例
|
27天前
|
SQL 关系型数据库 MySQL
12 PHP配置数据库MySQL
路老师分享了PHP操作MySQL数据库的方法,包括安装并连接MySQL服务器、选择数据库、执行SQL语句(如插入、更新、删除和查询),以及将结果集返回到数组。通过具体示例代码,详细介绍了每一步的操作流程,帮助读者快速入门PHP与MySQL的交互。
34 1
|
29天前
|
SQL 关系型数据库 MySQL
go语言数据库中mysql驱动安装
【11月更文挑战第2天】
39 4