[MySQL]复杂查询(进阶)

news2024/11/16 5:31:45


专栏简介 :MySql数据库从入门到进阶.

题目来源:leetcode,牛客,剑指offer.

创作目标:记录学习MySql学习历程

希望在提升自己的同时,帮助他人,,与大家一起共同进步,互相成长.

学历代表过去,能力代表现在,学习能力代表未来! 


目录

1.新增

2. 聚合查询

2.1 聚合函数

3. 分组查询(grop by)

4. having 

5. 联合查询

5.1 内连接

5.2 外连接

5.3 自连接

6. 子查询

7. 合并查询


1.新增

将查询结果作为values, 插入到指定表中.

语法:

insert into 表1 select * from 表2;

 示例:

将学生表1中的数据插入到学生表2中.

mysql> insert into student1 select * from student2;

mysql> select * from student1;
+------+------+
| id   | name |
+------+------+
|    1 | 张三 |
|    2 | 李四 |
|    3 | 王五 |
|    4 | 老六 |
+------+------+
4 rows in set (0.00 sec)

mysql> select * from student2;
+------+------+
| id   | name |
+------+------+
|    1 | 张三 |
|    2 | 李四 |
|    3 | 王五 |
|    4 | 老六 |
+------+------+
4 rows in set (0.00 sec)

Tips:

  • 查询表与插入表的列数和类型要匹配.
  • 所有select查询都可以和该操作组合使用.

2. 聚合查询

之前提到的条件查询都是基于列和列之间的查询, 而聚合查询针对某个列中所有的行来运算.

2.1 聚合函数

函数说明
count返回查询到的数据的数量
sum返回查询到数据的总和 (不是数字没有意义)
avg返回查询到数据的平均值 (不是数字没有意义)
max返回查询到数据的最大值 (不是数字没有意义)
min返回查询到数据的最小值 (不是数字没有意义)
  • count

语法:

select count(表达式) from 表名;
  • Tips: count(*)包含null所在的行. 

示例: 

统计班级有多少学生


  • sum

语法:

select sum(表达式) from 表名

示例:

统计数学总分


  • avg

语法:

select avg(表达式) from student;

示例:

统计平均总分


  • max

语法:

select max(表达式) from 表名;

示例:

返回英语最高分


  • min

语法:

select min(表达式) from 表名;

示例:

返回大于60分以上的数学最低分


3. 分组查询(grop by)

语法:

select 字段 from 表名 group by 字段

示例:

  • 单个字段分组

查出学生等级的种类:(按等级划分,去除重复的)

select grade from student group by grade; 


  • 多个字段分组

按名字和等级划分去除重复的同学:

select name from student group by name,grade;

Tip:此时将名字和等级看做是一个整体, 只有名字和等级都相同的才能分成一组, 其中一个不同就不是一组. 


  • 搭配聚合函数分组

查看表中相同人名的个数:

select name,count(*) from student group by name;


4. having 

wherehaving都是设定筛选条件的语句,有相似点也有不同点.

  • group by子句进行分组以后,, 分组之前筛选用where, 分组之后筛选用having.
  • having必须和group by 一起使用.
  • where之后不能使用聚合函数, having之后可以使用聚合函数.
  • having可以看做是对where的补充, where筛选出合适的数据having才能进行聚合操作.
字名作用
where 子句

1)对查询结果进行分组前, 将不符合where条件的行去掉, 即在分组之前过滤数据.

2)where 后面不可以使用聚合函数

3)过滤

having 子句

1)having 子句的作用是筛选满足条件的组, 即在分组之后过滤数据,.

2)having 后面可以使用聚合函数

3)过滤

4)支持所有的where操作.

MySQL语句执行顺序: 

示例:

显示平均工资高于1500的人的平均工资.

select name,avg(salary) from student group by name having avg(salary)>1500;


5. 联合查询

实际开发中数据往往来自不同的表, 所以需要多表联合查询, 多表联合查询本质是对多张表的数据取笛卡尔积(也就是全排列).列数是两个表列数之和, 行数是两个表行数之和.因此其中只有一部分数据是有效的, 需要后续相关操作进行筛选.

 Tips:关联表查询时可以对关联表使用别名, 更加直观.

筛选前: 

 筛选后:

 Tips:如果两张表中字段重名, 不加成员访问修饰符" . ", 会报错 ambigous(模糊不清的)

 为了使查询数据更加直观明了, 本文提供以下代码供后续案例使用.

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','张三','zhangsan@qq.com',1),
('00835','李四',null,1),
('00391','王五',null,1),
('00031','老六','xuxian@qq.com',1),
('00054','老师我作业忘带了',null,1),
('51234','芝士雪豹','xuebao@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),
-- 老外学英文
(80, 7, 2),(92, 7, 6);

5.1 内连接

内连接就是指结果仅包含符合连接条件的行, 参与连接的两个表都应符合连接条件.

语法:

1.from多个表简单明了,但只能实现内连接不能实现外连接.

select * from 表1,表2...;

2.join on可以既可以实现内连接也可以实现外连接. 

select * from 表1 join 表2 on...;
select * from 表1 inner join 表2 on...;

示例:

查询老六同学的全科成绩.

查询步骤:

  1. 分析需要联合的表(学生表和分数表), 然后计算笛卡尔积.
  2. 合法性筛选(分数表id对应学生id).
  3. 根据需求加入必要条件.xue
  4. 去要的列.

 1.计算学生表和分数表的笛卡尔积.(160多行数据, 大部分无效)

 2.分数表中id对应学生表中id

 3.学生姓名为老六

 4.去除不必要的列


查询所有同学的成绩, 及同学的个人信息.(学生表,课程表,分数表)

select student.name as 姓名,course.name as 课程名称,score.score from student,course,score where student.id = score.student_id and score.course_id = course.id;


5.2 外连接

连接结果不仅包含符合连接条件的行, 同时也包含不符合连接条件的行, 分为左外连接和右外连接.

语法:

左外连接:左表有多少数据就显示多少数据, 右边没有的就用null表示

select * from 表1 left join 表2 on 连接条件;

右外连接:右表有多少数据就显示多少数据, 左表没有的就用null表示

select * from 表1 right join 表2 on 条件;

示例:

假如王五同学转专业, 数据表还未同步他的成绩信息.

mysql> select * from student;
+------+------+
| id   | name |
+------+------+
|    1 | 张三 |
|    2 | 李四 |
|    3 | 王五 |
+------+------+
mysql> select * from score;
+------------+-------+
| student_id | score |
+------------+-------+
|          1 |    90 |
|          2 |    89 |
|          4 |    77 |
+------------+-------+
--左外连接
mysql> select * from student left join score on student.id = score.student_id;
+------+------+------------+-------+
| id   | name | student_id | score |
+------+------+------------+-------+
|    1 | 张三 |          1 |    90 |
|    2 | 李四 |          2 |    89 |
|    3 | 王五 |       NULL |  NULL |
+------+------+------------+-------+
--右外连接
mysql> select * from student right join score on student.id = score.student_id;
+------+------+------------+-------+
| id   | name | student_id | score |
+------+------+------------+-------+
|    1 | 张三 |          1 |    90 |
|    2 | 李四 |          2 |    89 |
| NULL | NULL |          4 |    77 |
+------+------+------------+-------+

5.3 自连接

自连接顾名思义就是自己和自己笛卡尔积, 自连接的效果就是把行转成列.不管和where子句还是having子句都是针对不同列之间的行进行操作, 如果只有一个列并且想要行与行之间进行比较, 就必须自连接.

语法:

select * from 表名 as 别名1,表名 as 别名2;

Tips:自连接必须给表起个别名, 否则两个相同的表连接会报错. 

示例:

查询java成绩高于计算机原理成绩的同学.

由图可以看出, java成绩和计算机原理成绩之间的比较在同一列, 所以需要行转列.

 自连接之后可以发现, 可以进行列与列之间的比较了, 本题针对的是同一同学不同课程, 所以筛选条件是两表的学生id相同.

mysql> select * from score as s1, score as s2 where s1.student_id = s2.student_id;

 最后添加条件完成比较.

mysql> select * from score as s1, score as s2 where s1.student_id = s2.student_id and s1.course_id = 3 and s2.course_id = 1 and s1.score>s2.score;
+-------+------------+-----------+-------+------------+-----------+
| score | student_id | course_id | score | student_id | course_id |
+-------+------------+-----------+-------+------------+-----------+
|  98.5 |          1 |         3 |  70.5 |          1 |         1 |
|  68.0 |          3 |         3 |  33.0 |          3 |         1 |
+-------+------------+-----------+-------+------------+-----------+

6. 子查询

子查询是指嵌套在其他sql语句中的select语句, 也叫嵌套查询.(本质上就是套娃)

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

示例:

返回与"老六"同学同班的同学.

--分步骤
mysql> select * from student where name = "老六";
+----+-------+------+---------------+------------+
| id | sn    | name | qq_mail       | classes_id |
+----+-------+------+---------------+------------+
|  4 | 00031 | 老六 | xuxian@qq.com |          1 |
+----+-------+------+---------------+------------+


mysql> select * from student where classes_id = 1 and name!="老六";
+----+-------+------------------+-----------------+------------+
| id | sn    | name             | qq_mail         | classes_id |
+----+-------+------------------+-----------------+------------+
|  1 | 09982 | 张三             | zhangsan@qq.com |          1 |
|  2 | 00835 | 李四             | NULL            |          1 |
|  3 | 00391 | 王五             | NULL            |          1 |
|  5 | 00054 | 老师我作业忘带了 | NULL            |          1 |
+----+-------+------------------+-----------------+------------+

--子查询一步完成
mysql> select * from student where classes_id = (select classes_id from student where name = "老六" ) and name!="老六";
+----+-------+------------------+-----------------+------------+
| id | sn    | name             | qq_mail         | classes_id |
+----+-------+------------------+-----------------+------------+
|  1 | 09982 | 张三             | zhangsan@qq.com |          1 |
|  2 | 00835 | 李四             | NULL            |          1 |
|  3 | 00391 | 王五             | NULL            |          1 |
|  5 | 00054 | 老师我作业忘带了 | NULL            |          1 |
+----+-------+------------------+-----------------+------------+

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

示例:

查询语文或英语课程的成绩信息.

1. (not) in 关键字

--分步骤查询
mysql> select * from course where name = "语文" or name = "英语";
+----+------+
| id | name |
+----+------+
|  4 | 语文 |
|  6 | 英语 |
+----+------+

mysql> select * from score where course_id = 4 or course_id = 6;
+-------+------------+-----------+
| score | student_id | course_id |
+-------+------------+-----------+
|  98.0 |          1 |         6 |
|  72.0 |          4 |         6 |
|  43.0 |          6 |         4 |
|  79.0 |          6 |         6 |
|  92.0 |          7 |         6 |
+-------+------------+-----------+

--多行子查询
mysql> select * from score where course_id in (select id from course where name = "语文" or name = "英语");
+-------+------------+-----------+
| score | student_id | course_id |
+-------+------------+-----------+
|  98.0 |          1 |         6 |
|  72.0 |          4 |         6 |
|  43.0 |          6 |         4 |
|  79.0 |          6 |         6 |
|  92.0 |          7 |         6 |
+-------+------------+-----------+

2. (not) exists 关键字

由于 in 关键字查询结果在内存中, 如果内存中存不下可以考虑使用exists关键字, 但exists关键字执行效率低下, 且可读性差.不如分步查询.


 

7. 合并查询

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

Tips:

  • union查询结果会去重, union all 可以保留多份.
  • or 只能联合一个表中的结果, union 可以联合多个表中的.
  • union

示例:

查询id<3 或者名字为"英文"的课程

mysql> select * from course where id<3 union select * from course where name = "英语";
+----+--------------+
| id | name         |
+----+--------------+
|  1 | Java         |
|  2 | 中国传统文化 |
|  6 | 英语         |
+----+--------------+
  • union all

示例:

查询id<3 或者名字为"java"的课程

mysql> select * from course where id<3 union all select * from course where name = "Java";
+----+--------------+
| id | name         |
+----+--------------+
|  1 | Java         |
|  2 | 中国传统文化 |
|  1 | Java         |
+----+--------------+

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/12286.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Web UI 自动化测试:如何使用隐私模式进行测试

来啦老铁&#xff01; 这两天有个任务需要在桌面端 UI 自动化中使用隐私模式进行测试&#xff0c;之前没有用过&#xff0c;且在调研的时候还是小小花了点时间各种查资料的&#xff0c;因此做一下记录&#xff1b; 学习路径 1、Chrome 浏览器配置&#xff1b; 2、Edge 浏览…

电脑换cpu要重装系统吗

​cpu是一台电脑的控制以及运算核心&#xff0c;有十分重要的作用&#xff0c;不少小伙伴会遇到更换cpu的问题&#xff0c;所以小伙伴会提前了解换cpu要重装系统吗或者换cpu后bios如何设置的这类问题&#xff0c;接下来小编就为大家带来了详细的介绍&#xff0c;感兴趣的用户可…

(七)Bean的实例化方式

文章目录环境Bean的实例化方式通过构造方法实例化通过简单工厂模式实例化通过工厂方法模式实例化通过FactoryBean接口实例化BeanFactory和FactoryBean的区别BeanFactoryFactoryBean工厂Bean的使用&#xff1a;注入自定义Date上一篇&#xff1a;&#xff08;六&#xff09;Sprin…

【免杀前置课——Windows编程】十二、线程同步——一文讲懂什么是线程同步、原子操作函数、临界区、互斥体(激发态与非激发态区别)

线程同步线程同步多线程运行同一操作对象问题解决方案A:原子操作函数解决方案B:临界区解决方案C:互斥体激发态与非激发态互斥体优点:线程同步 多线程运行同一操作对象问题 #include<iostream> #include<Windows.h>LONG g_count 0; DWORD WINAPI myThreadProc1(_…

C语言工具——Visual Studio 的安装

很多新手朋友们&#xff0c;反应使用 IE 浏览器下载 Visual Studio 下载不下来&#xff0c;此时我们可以在 IE 浏览器上先装一个谷歌浏览器&#xff1a; https://chrom.lkcyl.cn/ . 然后打开谷歌&#xff0c;输入 VS 2019 的下载地址&#xff1a;https://learn.microsoft.com/…

深入浅出带你了解PHAR反序列化

前情提要 为了丰富自己是知识体系&#xff08;为了日更薅羊毛&#xff09;&#xff0c;我最近频繁翻阅MDN的文档&#xff0c;果然MDN文档常看常新。 最近翻到CSS部分&#xff0c;然后打开了伪类这一栏&#xff0c;好家伙&#xff0c;快60个了&#xff08;包括实验中的&#x…

【EC200U】 SIM卡使用

EC200U SIM卡SIM卡是什么SIM卡分类Quecpython SIM库调用获取sim卡的状态获取IMSI获取ICCID运行测试我们物联网要用到SIM卡&#xff0c;这张卡是4G应用的基础&#xff0c;许多功能都需要用到SIM卡。买此类板子别忘了买SIM卡哦。 SIM卡是什么 SIM卡是(Subscriber Identity Modul…

影刀连接Mysql数据库

这里写自定义目录标题官方教程下载安装Mysql-connector配置数据源填写影刀的配置的向导官方教程 官方影刀下载mysql连接教程 https://www.winrobot360.com/yddoc/language/zh-cn/%E6%8C%87%E4%BB%A4%E6%96%87%E6%A1%A3/%E5%85%B6%E4%BB%96/%E6%95%B0%E6%8D%AE%E5%BA%93/%E8%BF…

初步探索GraalVM--云原生时代JVM黑科技

1 云原生时代Java语言的困境 经过多年的演进&#xff0c;Java语言的功能和性能都在不断的发展和提高&#xff0c;诸如即时编译器、垃圾回收器等系统都能体现Java语言的优秀&#xff0c;但是想要享受这些功能带来的提升都需要一段时间的运行来达到最佳性能&#xff0c;总的来说…

linux笔记(5):按照东山派的官方教程编译buildroot(东山哪吒,D1-H)踩坑记录

文章目录1.编译流程1.1获取sdk源码1.2 补充&#xff1a;下载riscv64-glibc-gcc-thead_20200702.tar.xz1.3 补充&#xff1a;安装mtool工具1.4 安装必要依赖包1.5 编译sdcard 最小系统镜像1.6 烧录最小镜像系统到tf(SD)卡1.6.1 安装烧录工具1.6.2 格式化SD卡1.6.3 烧录镜像到sd卡…

杂篇(一)

开篇词 我本是红尘一俗客&#xff0c;没有那文人酸腐气。 曾几何时&#xff0c;梳理收藏夹&#xff0c;发现了很久前收藏的一位前端大佬的个人博客&#xff1a;怡红院落 &#xff0c;因为领域不同&#xff0c;之前一直没有拜读过他的文章。 我尚且无法判断怡红公子购买的域名…

【Log日志】springboot项目中集成Log日志详解

springboot项目中集成Log日志详解一、Log日志介绍1.Log 日志组件主要作用及用途2.日志的级别Level级别控制3.日志的输出Import3.1 快速使用3.2 日志文件输出3.3 自定义配置4. Spring Boot 日志组件 Log Plugin二、Spring Boot Logback1.依赖配置 Pom.xml2.使用 YML 配置 logbac…

Linux操作系统~系统文件IO,什么是文件描述符fd?什么是vfs虚拟文件系统

目录 1.open() &#xff08;1&#xff09;.第二个参数flags—通过比特位传多组标记 2.文件描述符fd&#xff08;open函数的返回值&#xff09; &#xff08;1&#xff09;.fd的本质 &#xff08;2&#xff09;.vfs-虚拟文件系统&#xff08;一切皆文件&#xff09; &…

MySQL Binlog 简介

MySQL Binlog Binlog 记录了所有的 DDL 和 DML(除了数据查询语句)语句&#xff0c;以事件形式记录&#xff0c;还包含语句所执行的消耗的时间&#xff0c;MySQL 的二进制日志是事务安全型的。 一般来说开启二进制日志大概会有 1%的性能损耗。 二进制日志包括两类文件&#xf…

seccon 2022 quals -simplemod

文章目录题外话调试思路如何找到对应的link_map分析do_lookup_x我的构造payloadall_exp总结题外话 这个题应该是seccon解题数量最少的了 这个题目其实和babyfile差不多&#xff0c;都是考虑0 lick,整体而言通过这两个题可以感受到出题者对于IO以及dl_resolv的理解深入 这个题目…

阻止移动端 touchmove 与 scroll 事件冲突

在移动端开发过程中&#xff0c;如果要实现一个元素或按钮的拖动定位&#xff0c;会出现很多坑。例如&#xff1a;元素上下移动过程中&#xff0c;会触发 body 的 scroll 事件&#xff0c;导致整体的位置偏移&#xff0c;这时就需要 阻止移动端 touchmove 与 scroll 事件冲突 。…

confluent-kafka-go依赖库编译体验优化

文章目录问题描述&#xff1a;解决方案1&#xff1a;编写Dockerfile文件2&#xff1a;运行Docker镜像3&#xff1a;进入镜像进行编译4&#xff1a;将编译成功的二进制文件复制到本机参考地址问题描述&#xff1a; ​ 在项目中使用了go的kafka库confluent-kafka-go&#xff0c;…

力扣(LeetCode)2. 两数相加(C++\C)

模拟 模拟加法运算&#xff0c;设置进位数 ttt &#xff0c; t(l1t(l1t(l1->vall2vall2vall2->valt)%10valt)\%10valt)%10 即为当前位上的数&#xff0c; t/10t/10t/10 即是进位数。 设置哑结点&#xff0c;便于操作头结点。 模拟上述操作&#xff0c;最后返回哑结点的…

Windows11更新最新系统版本后无法播放媒体声音

故障机器Dell为例 step1&#xff1a;检测系统提示音是否正常&#xff0c;正常可观察第二步&#xff1b; step2:打开计算机管理-设备管理器-观察声音设备是否正常&#xff0c;可右键编辑重启驱动 step3&#xff1a;打开无法播放媒体声音的设备查看设置&#xff0c;Firefox为例 …

腾讯魏巍:Eunomia云原生资源编排优化

2022年11月10日&#xff0c;在中国信通院、腾讯云、FinOps产业标准工作组联合发起的《原动力x云原生正发声 降本增效大讲堂》系列直播活动第10讲上&#xff0c;腾讯Light云计算平台负责人魏巍分享了Eunomia云原生资源编排优化实践。本文整理自魏巍的分享。 云上资源优化背景 相…