MySQL进阶查询

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
云数据库 RDS PostgreSQL,高可用系列 2核4GB
简介: 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


相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
相关文章
|
2月前
|
SQL 缓存 监控
MySQL缓存机制:查询缓存与缓冲池优化
MySQL缓存机制是提升数据库性能的关键。本文深入解析了MySQL的缓存体系,包括已弃用的查询缓存和核心的InnoDB缓冲池,帮助理解缓存优化原理。通过合理配置,可显著提升数据库性能,甚至达到10倍以上的效果。
|
2月前
|
SQL 存储 关系型数据库
MySQL体系结构详解:一条SQL查询的旅程
本文深入解析MySQL内部架构,从SQL查询的执行流程到性能优化技巧,涵盖连接建立、查询处理、执行阶段及存储引擎工作机制,帮助开发者理解MySQL运行原理并提升数据库性能。
|
4月前
|
SQL 人工智能 关系型数据库
如何实现MySQL百万级数据的查询?
本文探讨了在MySQL中对百万级数据进行排序分页查询的优化策略。面对五百万条数据,传统的浅分页和深分页查询效率较低,尤其深分页因偏移量大导致性能显著下降。通过为排序字段添加索引、使用联合索引、手动回表等方法,有效提升了查询速度。最终建议根据业务需求选择合适方案:浅分页可加单列索引,深分页推荐联合索引或子查询优化,同时结合前端传递最后一条数据ID的方式实现高效翻页。
267 0
|
2月前
|
SQL 关系型数据库 MySQL
MySQL的查询操作语法要点
储存过程(Stored Procedures) 和 函数(Functions) : 储存过程和函数允许用户编写 SQL 脚本执行复杂任务.
220 14
|
2月前
|
SQL 关系型数据库 MySQL
MySQL的查询操作语法要点
以上概述了MySQL 中常见且重要 的几种 SQL 查询及其相关概念 这些知识点对任何希望有效利用 MySQL 进行数据库管理工作者都至关重要
102 15
|
2月前
|
SQL 监控 关系型数据库
SQL优化技巧:让MySQL查询快人一步
本文深入解析了MySQL查询优化的核心技巧,涵盖索引设计、查询重写、分页优化、批量操作、数据类型优化及性能监控等方面,帮助开发者显著提升数据库性能,解决慢查询问题,适用于高并发与大数据场景。
|
2月前
|
SQL 关系型数据库 MySQL
MySQL入门指南:从安装到第一个查询
本文为MySQL数据库入门指南,内容涵盖从安装配置到基础操作与SQL语法的详细教程。文章首先介绍在Windows、macOS和Linux系统中安装MySQL的步骤,并指导进行初始配置和安全设置。随后讲解数据库和表的创建与管理,包括表结构设计、字段定义和约束设置。接着系统介绍SQL语句的基本操作,如插入、查询、更新和删除数据。此外,文章还涉及高级查询技巧,包括多表连接、聚合函数和子查询的应用。通过实战案例,帮助读者掌握复杂查询与数据修改。最后附有常见问题解答和实用技巧,如数据导入导出和常用函数使用。适合初学者快速入门MySQL数据库,助力数据库技能提升。
|
3月前
|
存储 关系型数据库 MySQL
使用命令行cmd查询MySQL表结构信息技巧分享。
掌握了这些命令和技巧,您就能快速并有效地从命令行中查询MySQL表的结构信息,进而支持数据库维护、架构审查和优化等工作。
375 9
|
2月前
|
SQL 监控 关系型数据库
MySQL高级查询技巧:子查询、联接与集合操作
本文深入解析了MySQL高级查询的核心技术,包括子查询、联接和集合操作,通过实际业务场景展示了其语法、性能差异和适用场景,并提供大量可复用的代码示例,助你从SQL新手进阶为数据操作高手。
|
4月前
|
人工智能 Java 关系型数据库
Java的时间处理与Mysql的时间查询
本文总结了Java中时间与日历的常用操作,包括时间的转换、格式化、日期加减及比较,并介绍了MySQL中按天、周、月、季度和年进行时间范围查询的方法,适用于日常开发中的时间处理需求。

推荐镜像

更多
下一篇
oss云网关配置