你听过最孤独的话是什么?
同学,code就剩你没提交了
今天讨论的话题是
MySQL执行顺序
???
先养眼,再看题
❤️
今天还是小姐姐
前言
相信有不少小伙伴都是谈sql色变
什么是sql
sql怎么写
sql怎么又报错了
致命三连
那么在此
我也会将sql的一个大致模版讲解给大家
以后大家写sql可以照着这个模版写就好了
[toc]
- MySQL执行过程
- Demo
- 开始分析
- 1. FROM student temp
- 2. WHERE
- 3. GROUP BY name
- 4. COUNT(name) AS num
- 5. HAVING num >= 2
- 6. ORDER BY num DESC
- 7. LIMIT 0,2
- 备注:JOIN
- 总结
MySQL执行过程
> SQL语言,本身就是对MySQL数据查询的语言。并且也是脚本式语言,可直接运行在数据库上。
虽然说不同的数据库有不同的方言,有各自的性格,比如trim(),ifnull()等方法在oracle数据库中就没有,但是top()等方法在MySQL中就没有。
其实核心思想都是一样的,都是为了对数据库进行操作。只是,不同的数据库对同一条SQL语句的底层实现方式不同罢了。
其实就好像JAVA接口一样,不同的数据库,接口的实现类也不同,但是对同一条SQL语句的执行是相同的。
MySQL就是个关系型数据库,由二维表的形式存储数据,使用行和列对数据进行CRUD。
Demo
我们就用一个简单的demo来解释一条sql语句的执行流程分析。
首先,创建表student,有自增id,学生姓名name,学科subject,成绩grade
建表语句
-- 创建student_temp表DROP TABLE IF EXISTS student_temp;CREATE TABLE student_temp( id int(5) NOT NULL AUTO_INCREMENT, name varchar(10) DEFAULT NULL, subject varchar(10) DEFAULT NULL, grade double(4, 1) DEFAULT NULL, PRIMARY KEY (id)) ENGINE = InnoDB DEFAULT CHARSET = utf8;
插入语句(insert into 或 insert select)
-- 向student_temp表插入数据student_tempinsert into student_temp (name, subject, grade)select 'Tom', '语文', 88union allselect 'Tom', '数学', 99union allselect 'Tom', '外语', 55;INSERT INTO student_temp(name, subject, grade)VALUES ('Jerry', '语文', 67);INSERT INTO student_temp(name, subject, grade)VALUES ('Jerry', '数学', 44);INSERT INTO student_temp(name, subject, grade)VALUES ('Jerry', '外语', 55);INSERT INTO student_temp(name, subject, grade)VALUES ('Speike', '语文', 56);INSERT INTO student_temp(name, subject, grade)VALUES ('Speike', '数学', 35);INSERT INTO student_temp(name, subject, grade)VALUES ('Speike', '外语', 77);
这是表的数据
id | name | subject | grade |
1 | Tom | 语文 | 88 |
2 | Tom | 数学 | 99 |
3 | Tom | 外语 | 55 |
4 | Jerry | 语文 | 67 |
5 | Jerry | 数学 | 44 |
6 | Jerry | 外语 | 55 |
7 | Speike | 语文 | 56 |
8 | Speike | 数学 | 35 |
9 | Speike | 外语 | 77 |
开始分析
需求:要求查询出挂科数目多于两门(包含两门)的前两名学生的姓名,如果挂科数目相同按学生姓名升序排列
SELECT name, COUNT(name) AS numFROM student_tempWHERE grade < 60GROUP BY nameHAVING num >= 2ORDER BY num DESC, name ASCLIMIT 0,2;
查询结果:
name | num |
Jerry | 2 |
Speike | 2 |
下面,我们开始剖析这句sql
你品,你细细的品
1. FROM stuednt_temp
> 负责将数据插入到内存中
mysql在计算机中是一个进程,cpu会给这个进程分配一个内存空间(类似于yarn)
2. WHERE grade < 60
> 会将数据进行过滤,筛选出符合条件的数据,并声称一张临时表放进去(基于内存的)
结果如下:
id | name | subject | grade |
3 | Tom | 外语 | 55 |
5 | Jerry | 数学 | 44 |
5 | Jerry | 外语 | 55 |
7 | Speike | 语文 | 56 |
8 | Speike | 数学 | 35 |
3. GROUP BY name
> 会将刚刚的结果的临时表进行切分成若干个临时表。
1. 当没有GROUP BY时,SELECT会根据后面的条件对内存中上面的临时表进行读取
2. 当有GROUP BY时,会将切分后的数据SELECT,再根据参与分组的字段或聚合函数生成结果(聚合函数自动忽略空格)
so,刚内存中的那张临时表,就被GROUP BY name切分为3张临时表
结果如下 :
- 表1 temp_1
id | name | subject | grade |
3 | Tom | 外语 | 55 |
- 表2 temp_2
id | name | subject | grade |
5 | Jerry | 数学 | 44 |
6 | Jerry | 外语 | 55 |
- 表3 temp_3
id | name | subject | grade |
7 | Speike | 语文 | 56 |
8 | Speike | 数学 | 35 |
4. COUNT(name) AS num
> 再次形成一张临时表
再根据聚合参数count()再次形成一张临时表
SELECT name , count(name) as num from temp_1;SELECT name , count(name) as num from temp_2;SELECT name , count(name) as num from temp_3;
结果如下:
name | num |
Tom | 1 |
Jerry | 2 |
Speike | 2 |
5. HAVING num >= 2
> 再次对如上结果进行过滤,生成一张新的临时表
这个时候,我们就能看出来WHERE和HAVING的不同:
HAVING是在GROUP BY之后进行使用。
WHERE是对FROM student_temp从数据库文件加载到内存中进行过滤
HAVING是对SELECT执行后的临时表进行过滤,所以HAVING只能对SELECT的字段进行操作,并生成一张临时表
name | num |
Jerry | 2 |
Speike | 2 |
6. ORDER BY num DESC
> 对内存中的临时表按照num和name进行排序操作
num是DESC降序,name是ASC升序
ORDER BY num DESC, name ASC
name | num |
Jerry | 2 |
Speike | 2 |
7. LIMIT 0,2
取排序后的前两个
name | num |
Jerry | 2 |
Speike | 2 |
备注:JOIN
join表示要关联的表,on是要连接的条件。
通过from和join指出要执行的table_A和table_B。
首先通过笛卡尔积产生临时表Temp1
通过on生成临时表Temp2
简单来讲就是通过Table_A,生成一张临时表Temp1,然找到Tabe_B的id和Table_A的id相同的部分组成表Temp2,Temp2里面包含了两表相同的数据。
总结
以上就是一条SQL的执行过程
so,我们以后写SQL也要有如下模版
SELECT XXXFROM XXXWHERE XXXGROUP BY XXXHAVING XXXORDER BY XXXLIMIT XXX;
附图如下:
阳光明媚 清风徐来
如果不曾见过阳光,我本可以忍受黑暗
Hi GuoDaXiong
我是狗子
祝你幸福