首页 > 数据库 >SQL 的执行顺序,你搞清楚了吗?

SQL 的执行顺序,你搞清楚了吗?

时间:2023-12-20 09:23:19浏览次数:32  
标签:顺序 搞清楚 having 分组 SQL 筛选 where id

这是一条标准的查询语句:

 

这是我们实际上SQL执行顺序:

  • from 子句组装来自不同数据源的数据;
  • where 子句基于指定的条件对记录行进行筛选;
  • group by 子句将数据划分为多个分组;
  • 使用聚集函数进行计算;
  • 使用 having 子句筛选分组;
  • 计算所有的表达式;
  • select 的字段;
  • 使用 order by 对结果集进行排序。

SQL 语言不同于其他编程语言的最明显特征是处理代码的顺序。在大多数据库语言中,代码按编码顺序被处理。但在 SQL 语句中,第一个被处理的子句式 FROM,而不是第一出现的 SELECT。

SQL 查询处理的步骤:

  • FROM <left_table>
  • <join_type> JOIN <right_table>
  • ON <join_condition>
  • WHERE <where_condition>
  • GROUP BY <group_by_list>
  • WITH {CUBE | ROLLUP}
  • HAVING <having_condition>
  • SELECT (9) DISTINCT
  • ORDER BY <order_by_list>
  • <TOP_specification> <select_list>

以上每个步骤都会产生一个虚拟表,该虚拟表被用作下一个步骤的输入。这些虚拟表对调用者(客户端应 用程序或者外部查询)不可用。只有最后一步生成的表才会会给调用者。如果没有在查询中指定某一个子句, 将跳过相应的步骤。

 

数据的关联过程

数据库中的两张表

 

from&join&where

用于确定我们要查询的表的范围,涉及哪些表。选择一张表,然后用join连接

from table1 join table2 on table1.id=table2.id

 

选择多张表,用where做关联条件

from table1,table2 where table1.id=table2.id

 

我们会得到满足关联条件的两张表的数据,不加关联条件会出现笛卡尔积。

 

group by

按照我们的分组条件,将数据进行分组,但是不会筛选数据。比如我们按照即id的奇偶分组

 

having&where

having中可以是普通条件的筛选,也能是聚合函数。而where只能是普通函数,一般情况下,有having可以不写where,把where的筛选放在having里,SQL语句看上去更丝滑。

使用where再group by

先把不满足where条件的数据删除,再去分组

使用group by再having

先分组再删除不满足having条件的数据,这两种方法有区别吗,几乎没有!举个例子:100/2=50,此时我们把100拆分(10+10+10+10+10…)/2=5+5+5+…+5=50,只要筛选条件没变,即便是分组了也得满足筛选条件,所以where后group by 和group by再having是不影响结果的!不同的是,having语法支持聚合函数,其实having的意思就是针对每组的条件进行筛选。我们之前看到了普通的筛选条件是不影响的,但是having还支持聚合函数,这是where无法实现的。当前数据分组情况

 

执行having的筛选条件,可以使用聚合函数。筛选掉工资小于各组平均工资的having salary<avg(salary)

 

select

分组结束之后,我们再执行select语句,因为聚合函数是依赖于分组的,聚合函数会单独新增一个查询出来的字段,这里用紫色表示,这里我们两个id重复了,我们就保留一个id,重复字段名需要指向来自哪张表,否则会出现唯一性问题。最后按照用户名去重。

select employee.id,distinct name,salary, avg(salary)

 

将各组having之后的数据再合并数据。

 

order by

最后我们执行order by 将数据按照一定顺序排序,比如这里按照id排序。如果此时有limit那么查询到相应的我们需要的记录数时,就不继续往下查了。

 

limit

记住limit是最后查询的,为什么呢?假如我们要查询年级最小的三个数据,如果在排序之前就截取到3个数据。实际上查询出来的不是最小的三个数据而是前三个数据了,记住这一点。我们如果limit 0,3窃取前三个数据再排序,实际上最少工资的是2000,3000,4000。你这里只能是4000,5000,8000了。

 

标签:顺序,搞清楚,having,分组,SQL,筛选,where,id
From: https://www.cnblogs.com/shujuyr/p/17915379.html

相关文章

  • PostgreSQL中的事务隔离级别
    PostgreSQL中的事务隔离级别在确保多用户数据库环境中的数据一致性、完整性和并发控制方面起着至关重要的作用。当多个事务并发执行时,隔离级别定义了它们之间的相互隔离的程度。PostgreSQL提供了一系列的隔离级别,每个级别都有自己的一套保证和权衡,允许开发人员根据特定的需求定制......
  • MySQL函数
    字符串函数字符串相关操作的函数举个例子:①concat(str1,str2,........):字符串拼接--将product表中pname与price进行拼接selectconcat(pname,price)fromproduct;效果展示: ②lower(str):转成小写--将'SMIT'转成小写selectlower('SMIT')fromdual;效果展示:③......
  • mysql笔记
    MySQL数据库B站资源网盘资源sql数据库提取码:mmmmDB、DBMS、SQL的关系DB:Database,数据库,数据库在硬盘上以文件的形式存在。DBMS:DatabaseManagementSystem,数据库管理系统,如:MySQL,Oracle,DB2,Sybase,SqlServer等。SQL:StructureQueryLanguage,结构化查询语言,是一门标准通用的......
  • MySQL数据库故障恢复方案
    针对以上问题,技术部门拟定了恢复方案,内容如下:1、故障类型分类:在此次故障中,由于未对生产环境进行备份也未开启binlog日志,无法直接还原数据库,属于典型表内mysql-delete数据误删除。2、故障分析与可行性方案制定:对于mysqlinnodb误删除导致记录丢失的恢复方案有三种,分别是备份还原、......
  • 第十二单元 `T-SQL` 编程
    createdatabasestep2_unit12;gousestep2_unit12;go--部门表CREATETABLE[dbo].[Department]([Id][int]PRIMARYKEYIDENTITY(1,1)NOTNULL,[Name][varchar](20)NULL);--职位表CREATETABLE[dbo].[Job]([Id][int]PRIMARYKEYIDENTITY(1,1)......
  • mysql8 WIN10密码重置处理
    1、设置权限:mysqld--console--skip-grant-tables--shared-memory2、管理运行CMD:mysql-urooy-p;无需认证,直接回车3、修改USER密码置空: usemysqlupdateusersetauthentication_string=''whereuser='root';4、退出mysql,执行命令:quit关闭以-con......
  • 连接数据库(mysql,orcle)
    链接mysql数据库前提:自行下载.jar包1、下载mysql-connector-java-5.1.28.jar驱动包,将包安装在Jmeter的\lib\ext目录下然后再在jmeter上点击打开导入mysql驱动包,( 添加一个线程组先)如下图所示:  添加配置元件中JDBCConnectionConfiguration  填写一下信息(注:写上vari......
  • Postgresql中PL/pgSQL代码块的语法与使用-声明与赋值、IF语句、CASE语句、循环语句
    场景PostGresSQL简介与Windows上的安装教程:https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/113981563除了标准SQL语句之外,PostgreSQL还支持使用各种过程语言(例如PL/pgSQL、C、PL/Tcl、PL/Python、PL/Perl、PL/Java等)创建复杂的过程和函数,称为存储过程(Store......
  • MySQL运维11-Mycat分库分表之应用指定分片
    一、应用指定分片此规则是在运行阶段有应用自主决定路由到那个分片,根据提供的字段,然后按照指定的规则,截取该字段的部分子字符串当做分片的依据,该分别方法比较灵活,适用于某个字段有几个特殊的字符串拼接而成的这种场景,例如:一个学校的学号:小学部的学号以0开头,形式为:0xxxxx(......
  • Docker部署MySQL
    1、拉取MySQL镜像dockerpullmysql:5.72、查看镜像dockerimages3、创建存储MySQL数据信息的目录在根目录下创建/data/docker/mysql目录,用于存储mysql的数据信息mkdir/data/docker/mysql-p4、宿主机创建MySQL配置文件4.1、创建conf目录在/data/docker/mysql目录下......