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

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

时间:2023-12-26 14:06:04浏览次数:37  
标签:顺序 搞清楚 数据 having 分组 SQL 筛选 where id

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

SQL 的执行顺序,你搞清楚了吗?_聚合函数

 

这是我们实际上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>

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

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

 

数据的关联过程

数据库中的两张表

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

 

from&join&where

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

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

 

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

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

 

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

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

 

group by

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

SQL 的执行顺序,你搞清楚了吗?_聚合函数_05

 

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无法实现的。当前数据分组情况

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

 

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

SQL 的执行顺序,你搞清楚了吗?_聚合函数_07

 

select

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

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

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

 

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

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

 

order by

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

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

 

limit

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

SQL 的执行顺序,你搞清楚了吗?_数据_11

 

标签:顺序,搞清楚,数据,having,分组,SQL,筛选,where,id
From: https://blog.51cto.com/u_12208527/8982827

相关文章

  • Mac安装Mysql5.7
    官网https://downloads.mysql.com/archives/community/下载Mysql5.7.31,再高5.7版本没有macOS选项安装安装完毕会弹出帐号密码这里要把密码记住,待会用mysqladmin重置密码时要用。启动mysql服务系统设置拉到最下面,启动mysql服务启动成功设置mysql服务端mysql命令别名aliasmysql=/usr......
  • 无涯教程-PostgreSQL - String函数
    PostgreSQL字符串函数主要用于字符串操作。下表详细介绍了重要的字符串函数-S.No.Name&描述1ASCII()返回最左边字符的数值2BIT_LENGTH()返回参数的长度(以位为单位)3CHAR_LENGTH()返回参数中的字符数4CHARACTER_LENGTH()CHAR_LENGTH()的同义词5CONCAT_WS......
  • 无涯教程-PostgreSQL - Numeric函数
    PostgreSQL数值函数主要用于数值运算和/或数学计算。下表详细介绍了数字函数-S.No.Name&描述1ABS()返回数值表达式的绝对值。2ACOS()返回数值表达式的反余弦值,如果该值不在-1到1之间,则返回NULL。3ASIN()返回数字表达式的反正弦值,如果值不在-1到1的范围内,则返回NU......
  • mysql 配置主从复制
    主库配置#BinaryLogging.#log-binlog-bin=mysql-bin#[必须]启用二进制日志#ErrorLogging.log-error="mysql-error.log"#ServerId.server-id=200#不同步的数据库,可设置多个binlog-ignore-db=information_schemabinlog-ignore-db=performance_schemabinlo......
  • 什么是 MySQL JDBC 连接池中最高效的连接检测语句?
    在回答这个问题之前,首先我们看看MySQL中有哪些常用的JDBC连接池:c3p0DBCPDruidTomcatJDBCPoolHikariCP这些连接池中,这些连接池中,c3p0是一个老牌的连接池,很多流行框架,在其老版本中,都将c3p0作为默认的连接池。DBCP和TomcatJDBCPool(Tomcat的默认连接池)是Apache......
  • MySQL8.0 OCP 103
    Choosethree.Whichthreerequirementsmustbeenabledforgroupreplication?对于组复制,必须启用哪些三个要求?A)replicationfiltersB)semi-syncreplicationpluginC)slaveupdateslogging更新日志记录D)binarylogchecksumE)primarykeyorprimarykeyequ......
  • Mysql报语法错误,排查竟然花了一个钟!!!!
    背景:最近协助远程同事开发一个功能,我调用同事写的接口,发现报错,,同事正在处理其他事情,暂时无暇顾及。遂自行解决。查看日志发现,发现一个inser语句报语法错误。解决过程:1、找到报错的日志,查看sql。如果没有,打开mybatis-plus日志输出。2、将sql复制出来在mysql客户端模拟执行,发现sql......
  • 无涯教程-PostgreSQL - ARRAY函数
    PostgreSQLARRAY_AGG函数用于将包含null的输入值连接到数组中。要了解ARRAY_AGG函数,请考虑将 COMPANY 记录为跟随-testdb#select*fromCOMPANY;id|name|age|address|salary----+-------+-----+-----------+--------1|Paul|32|California|......
  • MySQL查询慢,四种方案帮你解决!
    一般分页在系统中需要进行分页操作时,我们通常会使用LIMIT加上偏移量的方式实现,语法格式如下。SELECT...FROM...WHERE...ORDERBY...LIMIT...在有对应索引的情况下,这种方式一般效率还不错。但它存在一个让人头疼的问题,在偏移量非常大的时候,也就是翻页到很靠后的页面......
  • SQL SERVER 命名规范
    表命名规范      命名规范描述   使用规范   禁用规范统一采用单数形式   Order   Orders使用驼峰命名规范   UserAccout   userAccout避免中文拼音   UserAccout   YongHu避免下划线连接   UserAccout   User_Accout避免保留字......