MySQL进阶查询

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: MySQL进阶查询

1.新增查询


insert语句可以插入查询结果


drop table if exists student;
create table student(id int primary key auto_increment,name varchar(20));
insert into student values (null,'张三'),(null,'李四');
drop table if exists student2;
create table student2(id int primary key auto_increment,name varchar(20));
insert into student2 select *from student;


必须要保证查询的结果的列要和插入的表的列相匹配(列的名字无所谓,但是列的个数和类型需要匹配)


2.聚合查询


2.1 聚合函数


常见的聚合函数:


函数 说明
COUNT([DISTINCT] expr) 返回查询到的数据的 数量
SUM([DISTINCT] expr) 返回查询到的数据的 总和,不是数字没有意义
AVG([DISTINCT] expr) 返回查询到的数据的 平均值,不是数字没有意义
MAX([DISTINCT] expr) 返回查询到的数据的 最大值,不是数字没有意义
MIN([DISTINCT] expr) 返回查询到的数据的 最小值,不是数字没有意义



案例:

初始化测试数据


-- 创建考试成绩表
DROP TABLE IF EXISTS exam_result;
CREATE TABLE exam_result (
                             id INT,
                             name VARCHAR(20),
                             chinese DECIMAL(3,1),
                             math DECIMAL(3,1),
                             english DECIMAL(3,1)
);
-- 插入测试数据
INSERT INTO exam_result (id,name, chinese, math, english) VALUES
                                                              (1,'唐三藏', 67, 98, 56),
                                                              (2,'孙悟空', 87.5, 78, 77),
                                                              (3,'猪悟能', 88, 98.5, 90),
                                                              (4,'曹孟德', 82, 84, 67),
                                                              (5,'刘玄德', 55.5, 85, 45),
                                                              (6,'孙权', 70, 73, 78.5),
                                                              (7,'宋公明', 75, 65, 30),(null,null,null,null,null);


count:


微信图片_20230111122656.png

统计结果共有多少行


微信图片_20230111122652.png


count(列名),空值不会记录


微信图片_20230111122649.png


sum:

统计数学成绩总分


微信图片_20230111122646.png


avg:

统计平均分


微信图片_20230111122643.png


max

返回英语最高分


微信图片_20230111122641.png


min

返回七十分以上的数学最低分


微信图片_20230111122637.png


2.2 group by子句


group by子句能够根据查询结果,进行分组,把值相同的记录分成一组,然后可以针对每一组分别进行聚合。


测试数据初始化:


create table emp(
 id int primary key auto_increment,
 name varchar(20) not null,
 role varchar(20) not null,
 salary numeric(11,2)
);
insert into emp(name, role, salary) values
('马云','服务员', 1000.20),
('马化腾','游戏陪玩', 2000.99),
('孙悟空','游戏角色', 999.11),
('猪无能','游戏角色', 333.5),
('沙和尚','游戏角色', 700.33),
('隔壁老王','董事长', 12000.66);


查询每个角色的最高工资、最低工资和平均工资:


微信图片_20230111122632.png

注意:


微信图片_20230111122629.png


微信图片_20230111122627.png

在上图按照角色分组的查询结果中,每个记录都是相同角色的第一条记录;

说明在进行分组查询的时候,只有用来分组的这一列可以直接进行查询,其他列必须搭配聚合函数来查询。


2.3 having


在分组查询中,也可以进行条件筛选。

若在分组前指定条件,使用where语句,但若在分组后进行指定条件,就需要使用having语句。


查询除了猪无能以外每个岗位的平均薪资(分组前)


微信图片_20230111122623.png

查询平均薪资大于1000的岗位(分组后)


微信图片_20230111122620.png


3.联合查询


3.1 笛卡尔积


实际开发中往往数据来自不同的表,所以需要多表联合查询。多表查询是对多张表的数据取笛卡尔积:

假定两张表


微信图片_20230111122617.png

其笛卡尔积结果就是两张表进行排列组合的结果


微信图片_20230111122614.png

笛卡尔积结果的列数为两个表的列数之和,行数为两表行数之积。

在笛卡尔积的结果中我们可以再上图中发现,只有绿框部分的记录才是有效记录,这是因为笛卡尔积就是两张表直接进行排列组合的结果,并没设置条件,所以需要设置连接条件再进行查询,这样查询出来的结果才是有效记录。


create table student(id int,name varchar(20),classID int);
insert into student values (1,'张三',1),(2,'李四',1),(3,'王五',2),(4,'赵六',2);
create table class(classID int,name varchar(20));
insert into class values (1,'java100'),(2,'java101');
select * from student,class where student.classID=class.classID;


微信图片_20230111122610.png


以下测试数据初始化:


drop table if exists classes;
drop table if exists student;
drop table if exists course;
drop table if exists score;
create table classes (id int primary key auto_increment, name varchar(20), `desc` varchar(100));
create table student (id int primary key auto_increment, sn varchar(20),  name varchar(20), qq_mail varchar(20) ,
                      classes_id int);
create table course(id int primary key auto_increment, name varchar(20));
create table score(score decimal(3, 1), student_id int, course_id int);
insert into classes(name, `desc`) values
                                      ('计算机系2019级1班', '学习了计算机原理、C和Java语言、数据结构和算法'),
                                      ('中文系2019级3班','学习了中国传统文学'),
                                      ('自动化2019级5班','学习了机械自动化');
insert into student(sn, name, qq_mail, classes_id) values
                                                       ('09982','黑旋风李逵','xuanfeng@qq.com',1),
                                                       ('00835','菩提老祖',null,1),
                                                       ('00391','白素贞',null,1),
                                                       ('00031','许仙','xuxian@qq.com',1),
                                                       ('00054','不想毕业',null,1),
                                                       ('51234','好好说话','say@qq.com',2),
                                                       ('83223','tellme',null,2),
                                                       ('09527','老外学中文','foreigner@qq.com',2);
insert into course(name) values
                             ('Java'),('中国传统文化'),('计算机原理'),('语文'),('高阶数学'),('英文');
insert into score(score, student_id, course_id) values
-- 黑旋风李逵
(70.5, 1, 1),(98.5, 1, 3),(33, 1, 5),(98, 1, 6),
-- 菩提老祖
(60, 2, 1),(59.5, 2, 5),
-- 白素贞
(33, 3, 1),(68, 3, 3),(99, 3, 5),
-- 许仙
(67, 4, 1),(23, 4, 3),(56, 4, 5),(72, 4, 6),
-- 不想毕业
(81, 5, 1),(37, 5, 5),
-- 好好说话
(56, 6, 2),(43, 6, 4),(79, 6, 6),
-- tellme
(80, 7, 2),(92, 7, 6);


3.2 内连接


语法:


select 字段 from 表1 别名1 [inner] join 表2 别名2 on 连接条件 and 其他条件;
select 字段 from 表1 别名1,表2 别名2 where 连接条件 and 其他条件;

案例:


(1)查询“许仙”同学的 成绩


1.计算student表和score表的笛卡尔积


微信图片_20230111122606.png

2.给笛卡尔积加连接条件


微信图片_20230111122602.png

3.根据许仙这个名字进行筛选


微信图片_20230111122559.png

4.对查询结果的列进行精简,保留关注的,去掉不用的


微信图片_20230111122556.png

如果使用join on的方式,一样可以实现相同的效果


微信图片_20230111122553.png

(2)查询所有同学的总成绩,及同学的个人信息

需要进行分组聚合


1.计算student表和score表的笛卡尔积


微信图片_20230111122550.png

2.给笛卡尔积加连接条件


微信图片_20230111122547.png

3.按照人来分组(可以使用id、sn或者name)


微信图片_20230111122544.png

4.求总成绩,即聚合函数sum


微信图片_20230111122541.png

(3)查询所有同学的各科成绩及个人信息

需要三张表进行联合查询


1.对student表、course表、score表进行笛卡尔积


微信图片_20230111122536.png

2.加连接条件

分数表为中间表,需要学生表和分数表的学生id相同,课程表和分数表的课程id相同


微信图片_20230111122532.png

3.对查询结果进行列精简


微信图片_20230111122528.png

总结:

由上边的例子可以总结出,复杂的SQL很难将其一步到位,需要一步步来完成,一般遵循以下步骤。

1)笛卡尔积

2)指定连接条件

3)加上其他的条件

4)对查询的列进行结果精简


3.3 外连接


外连接分为左外连接和右外连接。如果联合查询,左侧的表完全显示我们就说是左外连接;右侧的表完全显示我们就说是右外连接。

当两张表中的数据一一对应时,内连接和外连接结果相同(join on内连接);但若不一一对应时,就会有很大的差别。


语法:


-- 左外连接,表1完全显示
select 字段名  from 表名1 left join 表名2 on 连接条件;
-- 右外连接,表2完全显示
select 字段 from 表名1 right join 表名2 on 连接条件;


微信图片_20230111122524.png

微信图片_20230111122518.png

微信图片_20230111122515.png

微信图片_20230111122510.png


若下图为两张表的关系


微信图片_20230111122506.png

则内连接为


微信图片_20230111122503.png

左连接为


微信图片_20230111122459.png

右连接为


微信图片_20230111122457.png

3.4 自连接


自连接是指在同一张表连接自身进行查询。(自己与自己笛卡尔积)

案例:

显示所有“计算机原理”成绩比“Java”成绩高的成绩信息

1.自身笛卡尔积


微信图片_20230111122454.png

2.加限定条件,对应两门课程


微信图片_20230111122451.png

3.继续加条件,“计算机原理”成绩比“Java”成绩高的成绩信息


微信图片_20230111122448.png


3.5 子查询


本质上就是把多个查询语句组合成一个查询语句


单行子查询:返回一行记录的子查询

案例:查询与“不想毕业” 同学的同班同学:

先找出不想毕业同学的班级id

根据班级id找到对应的同学


微信图片_20230111122445.png


多行子查询:返回多行记录的子查询

案例:查询“语文”或“英文”课程的成绩信息

先找到语文和英文的课程id

再在score表中根据课程id找到对应记录


微信图片_20230111122442.png


3.6 合并查询


在实际应用中,为了合并多个select的执行结果,可以使用集合操作符 union,union all。使用UNION和UNION ALL时,前后查询的结果集中,字段需要一致。


union

该操作符用于取得两个结果集的并集。当使用该操作符时,会自动去掉结果集中的重复行。

案例:查询id小于3,或者名字为“英文”的课程:

select * from course where id<3
union
select * from course where name='英文';
-- 或者使用or来实现
select * from course where id<3 or name='英文';


微信图片_20230111122437.png

union all

该操作符用于取得两个结果集的并集。当使用该操作符时,不会去掉结果集中的重复行。

案例:查询id小于3,或者名字为“Java”的课程

-- 可以看到结果集中出现重复数据Java
select * from course where id<3
union all
select * from course where name='英文';

4.导图总结

微信图片_20230111122427.png


相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
1月前
|
缓存 关系型数据库 MySQL
MySQL索引策略与查询性能调优实战
在实际应用中,需要根据具体的业务需求和查询模式,综合运用索引策略和查询性能调优方法,不断地测试和优化,以提高MySQL数据库的查询性能。
164 66
|
3天前
|
存储 Oracle 关系型数据库
索引在手,查询无忧:MySQL索引简介
MySQL 是一款广泛使用的关系型数据库管理系统,在2024年5月的DB-Engines排名中得分1084,仅次于Oracle。本文介绍MySQL索引的工作原理和类型,包括B+Tree、Hash、Full-text索引,以及主键、唯一、普通索引等,帮助开发者优化查询性能。索引类似于图书馆的分类系统,能快速定位数据行,极大提高检索效率。
27 8
|
6天前
|
SQL 关系型数据库 MySQL
MySQL 窗口函数详解:分析性查询的强大工具
MySQL 窗口函数从 8.0 版本开始支持,提供了一种灵活的方式处理 SQL 查询中的数据。无需分组即可对行集进行分析,常用于计算排名、累计和、移动平均值等。基本语法包括 `function_name([arguments]) OVER ([PARTITION BY columns] [ORDER BY columns] [frame_clause])`,常见函数有 `ROW_NUMBER()`, `RANK()`, `DENSE_RANK()`, `SUM()`, `AVG()` 等。窗口框架定义了计算聚合值时应包含的行。适用于复杂数据操作和分析报告。
44 11
|
9天前
|
存储 关系型数据库 MySQL
mysql怎么查询longblob类型数据的大小
通过本文的介绍,希望您能深入理解如何查询MySQL中 `LONG BLOB`类型数据的大小,并结合优化技术提升查询性能,以满足实际业务需求。
38 6
|
1月前
|
SQL 前端开发 关系型数据库
SpringBoot使用mysql查询昨天、今天、过去一周、过去半年、过去一年数据
SpringBoot使用mysql查询昨天、今天、过去一周、过去半年、过去一年数据
62 9
|
1月前
|
缓存 监控 关系型数据库
如何优化MySQL查询速度?
如何优化MySQL查询速度?【10月更文挑战第31天】
86 3
|
1月前
|
SQL NoSQL 关系型数据库
2024Mysql And Redis基础与进阶操作系列(5)作者——LJS[含MySQL DQL基本查询:select;简单、排序、分组、聚合、分组、分页等详解步骤及常见报错问题所对应的解决方法]
MySQL DQL基本查询:select;简单、排序、分组、聚合、分组、分页、INSERT INTO SELECT / FROM查询结合精例等详解步骤及常见报错问题所对应的解决方法
|
1月前
|
监控 关系型数据库 MySQL
数据库优化:MySQL索引策略与查询性能调优实战
【10月更文挑战第27天】本文深入探讨了MySQL的索引策略和查询性能调优技巧。通过介绍B-Tree索引、哈希索引和全文索引等不同类型,以及如何创建和维护索引,结合实战案例分析查询执行计划,帮助读者掌握提升查询性能的方法。定期优化索引和调整查询语句是提高数据库性能的关键。
257 1
|
1月前
|
SQL 关系型数据库 MySQL
定时任务频繁插入数据导致锁表问题 -> 查询mysql进程
定时任务频繁插入数据导致锁表问题 -> 查询mysql进程
51 1
|
1月前
|
监控 关系型数据库 MySQL
数据库优化:MySQL索引策略与查询性能调优实战
【10月更文挑战第26天】数据库作为现代应用系统的核心组件,其性能优化至关重要。本文主要探讨MySQL的索引策略与查询性能调优。通过合理创建索引(如B-Tree、复合索引)和优化查询语句(如使用EXPLAIN、优化分页查询),可以显著提升数据库的响应速度和稳定性。实践中还需定期审查慢查询日志,持续优化性能。
111 0