有关mysql中sql的执行顺序的小问题

今天工作中碰到一个sql问题,关于left join的,后面虽然解决了,但是通过此问题了解了一下sql的执行顺序

场景还原

为避免安全纠纷,把场景模拟。

有一个学生表-S,一个成绩表G

CREATE TABLE `test_student` (
 `id` bigint(20) NOT NULL COMMENT '学号',
	`sex` TINYINT DEFAULT '0' COMMENT '性别 0-男 1-女',
 `name` varchar(255) DEFAULT NULL COMMENT '姓名'
) ENGINE=InnoDB CHARSET=utf8mb4 COMMENT='学生表';

CREATE TABLE `test_score` (
 `id` bigint(20) NOT NULL COMMENT '学号',
 `score` int NOT NULL COMMENT '分数',
	`level` TINYINT COMMENT '成绩 0-不及格 1-及格 2-优良 3-优秀'
) ENGINE=InnoDB CHARSET=utf8mb4 COMMENT='成绩表';

-- 初始化学生
INSERT INTO test_student VALUES(1, 0, '张三'), (2, 0, '李四'), (3, 1, '王X芳');
-- 初始化成绩
INSERT INTO test_score VALUES(1, 10, 0), (2, 20, 0), (3, 100, 3);

现在有一个需求,查出学生的考试成绩,可能的sql

SELECT ts.name AS '名字', tc.score AS '分数'
FROM test_student ts
LEFT JOIN test_score tc
ON ts.id = tc.s_id;

一切都很顺利,突然,刚考完试,就转来一个学生

INSERT INTO test_student VALUES(4, 0, '新来的');

他没成绩,还是刚才的sql查

老师只要看参加考试的学生的成绩,怎么办

1.用inner join

SELECT ts.name AS '名字', tc.score AS '分数'
FROM test_student ts
INNER JOIN test_score tc
ON ts.id = tc.s_id;

2.加条件过滤

SELECT ts.name AS '名字', tc.score AS '分数'
FROM test_student ts
LEFT JOIN test_score tc
ON ts.id = tc.s_id
AND tc.score is NOT NULL
;

发现加了条件过滤还是不对,额,改用where呢

SELECT ts.name AS '名字', tc.score AS '分数'
FROM test_student ts
LEFT JOIN test_score tc
ON ts.id = tc.s_id
WHERE tc.score is NOT NULL
;

bingo,那where为什么就对了呢。

这就涉及到sql的执行顺序了

where与join on

从上面的例子推断

where会从结果集中过滤出符合条件的记录,不符合条件的丢弃

join操作:有时为了得到完整的结果,我们需要从两个或更多的表中获取结果。我们就需要执行 join。

除了我们在上面的例子中使用的 INNER JOIN(内连接),我们还可以使用其他几种连接。

下面列出了您可以使用的 JOIN 类型,以及它们之间的差异。

  • JOIN: 如果表中有至少一个匹配,则返回行
  • LEFT JOIN: 即使右表中没有匹配,也从左表返回所有的行
  • RIGHT JOIN: 即使左表中没有匹配,也从右表返回所有的行
  • FULL JOIN: 只要其中一个表中存在匹配,就返回行(mysql不支持,可以考虑用视图实现)

这里推荐一个写的通俗易懂的简单学习SQL的各种连接Join

sql顺序

从上面看到,在sql中,on是写在了where条件之前,那么数据库引擎分析执行sql时,是否on也是在where前面呢?

一般sql的写法顺序

1.SELECT [列名称 *代表所有的列]

2.FROM [表名称]

3.join_type JOIN [表名称]

4.ON [join条件]

5.WHERE [过滤条件]

6.GROUP BY [分组字段]

7.HAVING [分组条件]

8.ORDER BY [排序字段]

那么sql在执行时,顺序是怎样的呢?

标准的sql解析顺序为:

1.FROM    组装数据,来自不同数据源(表)

2.WHERE    根据条件过滤记录

3.GROUP BY 对数据分组

4.计算聚集函数,如avg,sum

5.使用HAVING子句筛选分组

6.计算所有表达式

7.使用ORDER BY对结果排序

那么sql的执行顺序呢?

1.FROM: 对前2个表执行笛卡尔积,生成虚表vt1

2.ON: 对vt1应用on条件,只有满足join_condition条件的才能插入虚表vt2

3.OUTER(join):如果指定了OUTER JOIN保留表(preserved table)中未找到的行将行作为外部行添加到vt2,生成t3,如果from包含两个以上表,则对上一个联结生成的结果表和下一个表重复执行步骤和步骤直接结束

4.WHERE: 对vt3进行where筛选,只有满足where条件的才能插入vt4

5.GROUP BY: 对vt4按group by字段分组,得到vt5

6.HAVING:对vt5应用HAVING筛选器只有使 having_condition 为true的组才插入vt6

7.SELECT:处理select列表产生vt7

8.DISTINCT:将重复的行从vt7中去除产生vt8

9.ORDER BY:将vt8的行按order by子句中的列 列表排序生成一个游标vc9

10.LIMIT(Mysql): 从vc9的开始处选择指定数量的行生成vt10 并返回调用者

到了这里,应该发现,要写好sql不容易。但是了解了sql的执行顺序,能在开发的同理,更好的帮助写出好的程序。

比如join表不能太多(先过滤条件然后再根据表连接 同时在表中建立相关查询字段的索引这样在大数据多表联合查询的情况下速度相当快),这种sql优化问题,下次再学习整理下。

实践之!

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • SQL语句执行顺序图文介绍

    大家好,我们的数据库已经介绍完了,这里给大家总结一下. 我们这段主要是学习了SQL的增删改查语句,其中查询是我们的重点.我们是以SQL Server 2005来学习的SQL语句,关于SQL Server的图形界面操作,和关于视图.数据库备份还原这些大家下来要下来看一下. 关于Oracle,我们都已经学习了SQL语句,那么Oracle其实已经学习了一大半,就接下来自己学习Oracle主要是看一下他的概念,Oracle和SQL Server还是有很大不同的,熟悉他的表空间这些概念,了解他的图形界面,

  • SQLServer中SELECT语句的执行顺序

    今天在写一条语句的时候,在查询分析器里边执行 要用10s,换用另外一种写法只用少于1s的时间,同事说是因为Sql句语执行顺序的原因.之前看过一点相 关的书,有一点印象,到网上找了资料,学习下. 逻辑查询处理步骤 复制代码 代码如下: (8)SELECT (9)DISTINCT (11)<TOP_specification> <select_list> (1)FROM <left_table> (3) <join_type> JOIN <right_ta

  • SQL Select语句完整的执行顺序

    1.from子句组装来自不同数据源的数据: 2.where子句基于指定的条件对记录行进行筛选: 3.group by子句将数据划分为多个分组: 4.使用聚集函数进行计算: 5.使用having子句筛选分组: 6.计算所有的表达式: 7.使用order by对结果集进行排序. 举例说明: 在学生成绩表中 (暂记为 tb_Grade), 把 "考生姓名"内容不为空的记录按照 "考生姓名" 分组, 并且筛选分组结果, 选出 "总成绩" 大于 600 分

  • sql和MySQL的语句执行顺序分析

    今天遇到一个问题就是mysql中insert into 和update以及delete语句中能使用as别名吗?目前还在查看,但是在查阅资料时发现了一些有益的知识,给大家分享一下,就是关于sql以及MySQL语句执行顺序: sql和mysql执行顺序,发现内部机制是一样的.最大区别是在别名的引用上. 一.sql执行顺序 (1)from (2) on (3) join (4) where (5)group by(开始使用select中的别名,后面的语句中都可以使用) (6) avg,sum....

  • SQL语句执行顺序详解

    我们做软件开发的,大部分人都离不开跟数据库打交道,特别是erp开发的,跟数据库打交道更是频繁,由于SQL 不同于与其他编程语言的最明显特征是处理代码的顺序.在大数编程语言中,代码按编码顺序被处理,但是在SQL语言中,第一个被处理的子句是FROM子句,尽管SELECT语句第一个出现,但是几乎总是最后被处理. 每个步骤都会产生一个虚拟表,该虚拟表被用作下一个步骤的输入.这些虚拟表对调用者(客户端应用程序或者外部查询)不可用.只是最后一步生成的表才会返回 给调用者.如果没有在查询中指定某一子句,将跳过

  • 有关mysql中sql的执行顺序的小问题

    今天工作中碰到一个sql问题,关于left join的,后面虽然解决了,但是通过此问题了解了一下sql的执行顺序 场景还原 为避免安全纠纷,把场景模拟. 有一个学生表-S,一个成绩表G CREATE TABLE `test_student` ( `id` bigint(20) NOT NULL COMMENT '学号', `sex` TINYINT DEFAULT '0' COMMENT '性别 0-男 1-女', `name` varchar(255) DEFAULT NULL COMMENT

  • MySql中sql语句执行过程详细讲解

    目录 前言: sql语句的执行过程: 查询缓存: 分析器: 优化器: 执行器: 总结 前言: 很多人都在使用mysql数据库,但是很少有人能够说出来整个sql语句的执行过程是怎样的,如果不了解执行过程的话,就很难进行sql语句的优化处理,也很难设计出来优良的数据库表结构.这篇文章主要是讲解一下sql语句的执行过程. sql语句的执行过程: 客户端.连接器.分析器.优化器.执行器.存储引擎几个阶段. 连接器的作用:管理链接.权限验证的处理. 分析器的作用:词法分析.语法分析. 优化器的作用:执行计

  • 详解一条sql语句在mysql中是如何执行的

    概览 最近开始在学习mysql相关知识,自己根据学到的知识点,根据自己的理解整理分享出来,本篇文章会分析下一个sql语句在mysql中的执行流程,包括sql的查询在mysql内部会怎么流转,sql语句的更新是怎么完成的. 一.mysql架构分析 下面是mysql的一个简要架构图: mysql主要分为Server层和存储引擎层 Server层:主要包括连接器.查询缓存.分析器.优化器.执行器等,所有跨存储引擎的功能都在这一层实现,比如存储过程.触发器.视图,函数等,还有一个通用的日志模块 bing

  • 一条SQL语句在MySQL中是如何执行的

    目录 一.mysql架构分析 1.1 连接器 1.2 查询缓存 1.3 分析器 1.4 优化器 1.5 执行器 二.语句分析 2.1 查询语句 2.2 更新语句 三.总结 一.mysql架构分析 下面是mysql的一个简要架构图: mysql主要分为Server层和存储引擎层 Server层:主要包括连接器.查询缓存.分析器.优化器.执行器等,所有跨存储引擎的功能都在这一层实现,比如存储过程.触发器.视图,函数等,还有一个通用的日志模块 binglog日志模块. 存储引擎: 主要负责数据的存储和

  • MySQL中SQL Mode的查看与设置详解

    MySQL中SQL Mode的查看与设置 MySQL可以运行在不同的模式下,而且可以在不同的场景下运行不同的模式,这主要取决于系统变量 sql_mode 的值.本文主要介绍一下这个值的查看与设置,主要在Mac系统下. 对于每个模式的意义和作用,网上很容易找到,本文不做介绍. 按作用区域和时间可分为3个级别,分别是会话级别,全局级别,配置(永久生效)级别. 会话级别: 查看- select @@session.sql_mode; 修改- set @@session.sql_mode='xx_mod

  • 一文告诉你Sql的执行顺序是怎样的

    学过 Sql,或了解过 Sql 的人,应该都会写下面这行代码: select * from t 上面代码表示查询 t 表中的所有信息,是 Sql 查询中最基础,最简单的一行代码,你可以把它理解成是其他编程语言中的Hello World. select *只是你迈入 Sql 大门的第一步,在真实工作中,肯定不止这么简单的.我们来看一个例子. 现在有下面一个表 t ,存储了每个商品类别的成交明细,我们需要通过下面这张表获取订单量大于10对应的类别,并从中取出订单量前3的商品类别,会有一些测试的订单(

  • Unity3D中脚本的执行顺序和编译顺序

    事件函数的执行顺序 先说一下执行顺序吧. 官方给出的脚本中事件函数的执行顺序如下图: 我们可以做一个小实验来测试一下: 在Hierarchy视图中创建三个游戏对象,在Project视图中创建三条脚本,如下图所示,然后按照顺序将脚本绑定到对应的游戏对象上: 三条脚本的代码完全一样,只是做了一点名称上的区分: using UnityEngine;using System.Collections;public class Scring0 : MonoBehaviour{    void Awake()

  • 细数MySQL中SQL语句的分类

    1:数据定义语言(DDL)   用于创建.修改.和删除数据库内的数据结构,如:1:创建和删除数据库(CREATE DATABASE || DROP  DATABASE):2:创建.修改.重命名.删除表(CREATE  TABLE || ALTER TABLE|| RENAME TABLE||DROP  TABLE):3:创建和删除索引(CREATEINDEX  || DROP INDEX)   2:数据查询语言(DQL)   从数据库中的一个或多个表中查询数据(SELECT)   3:数据操作语

  • C#类中方法的执行顺序是什么

    有些中级开发小伙伴还是搞不太明白在继承父类以及不同场景实例化的情况下,父类和子类的各种方法的执行顺序到底是什么,下面通过场景的举例来重新认识下方法的执行顺序: (下面内容涉及到了C#中的继承,构造函数,虚方法,虚方法的重写,new关键字等知识点) 场景一 有子类继承,但是只实例化父类:只执行A对象,输出A对象的信息 class A { public A() => Console.WriteLine("A的构造函数"); public virtual void Fun() =>

随机推荐