MySQL进阶查询

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介: 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


相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
21天前
|
关系型数据库 MySQL 数据库
轻松入门MySQL:精准查询,巧用WHERE与HAVING,数据库查询如虎添翼(7)
轻松入门MySQL:精准查询,巧用WHERE与HAVING,数据库查询如虎添翼(7)
|
21天前
|
缓存 关系型数据库 MySQL
MySQL查询优化:提速查询效率的13大秘籍(合理使用索引合并、优化配置参数、使用分区优化性能、避免不必要的排序和group by操作)(下)
MySQL查询优化:提速查询效率的13大秘籍(合理使用索引合并、优化配置参数、使用分区优化性能、避免不必要的排序和group by操作)(下)
|
6天前
|
SQL 关系型数据库 MySQL
mysql 数据库查询 查询字段用逗号隔开 关联另一个表并显示
mysql 数据库查询 查询字段用逗号隔开 关联另一个表并显示
17 2
|
8天前
|
关系型数据库 MySQL Shell
MySQL 查询
MySQL 查询
|
10天前
|
SQL 关系型数据库 MySQL
DQL语言之基础查询(mysql)
DQL语言之基础查询(mysql)
|
10天前
|
SQL 关系型数据库 MySQL
DQL语言之连接查询(mysql)
DQL语言之连接查询(mysql)
|
10天前
|
关系型数据库 MySQL
MySQL全局库表查询准确定位字段
information_schema.COLUMNS 详细信息查询
199 4
|
14天前
|
关系型数据库 MySQL
Mysql查询语句的执行顺序
Mysql查询语句的执行顺序
11 0
|
16天前
|
SQL 关系型数据库 MySQL
mysql多表查询、函数查询
mysql多表查询、函数查询
|
16天前
|
SQL 关系型数据库 MySQL
mysql基本查询、运算符、排序和分页
mysql基本查询、运算符、排序和分页