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

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

时间:2024-01-19 09:44:44浏览次数:34  
标签:顺序 搞清楚 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/ataoxz/p/17973969

相关文章

  • MySQL 的保留账号
    以下账号是MySQL中的保留账号,在mysql初始化的时候创建。>selectuser,host,authentication_string,account_lockedfrommysql.userwhereaccount_locked='Y';+------------------+-----------+------------------------------------------------------------------------+-......
  • MySQL int(1)、int(20) 的区别
    在设计数据库表的时候,经常需要设计一个id字段,它的类型一般都是整型int,经常会遇到int(1)、int(20)等。int的范围:有符号的整型范围是-2147483648~2147483647无符号的整型范围是0~4294967295参看MySQL手册,int(M):Mindicatesthemaximumdisplaywidthforintegertypes.int(......
  • mysql数据文件ibd恢复
    mysql数据文件ibd恢复2020-08-18 共4343人围观因某些原因把mysql给搞坏了,又没有备份,只剩data文件中各个库的.frm和.ibd文件了。通过不懈寻找度娘的努力,终于让我找到了一种恢复数据的方法。该方法的前提是,你需要记得每个表结构,字段名必不可少,字段类型最好能记得或者大概记得,......
  • Web安全-SQL注入常用函数(二)
    ★★实战前置声明★★文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与学习之用,读者将其信息做其他用途,由用户承担全部法律及连带责任,文章作者不承担任何法律及连带责任。1、MySQL数据库构成初始化安装MySQL数据库后(基于MySQL版本5.7.x),默认会创建4个系统数据库:#默认......
  • wireshark实践 - 调试spring连接mysql失败问题
    问题描述spring:datasource:driver-class-name:com.mysql.jdbc.Driverurl:jdbc:jdbc:mysql://122.224.147.xxx:90/dev?characterEncoding=utf8username:xxxpassword:xxxtype:com.alibaba.druid.pool.DruidDataSourceurl格式写错了(两个jdbc),然......
  • ubtunu安装mysql5.7
    1.官网:mysql下载链接官网地址 2.我们新建一个文件夹,路径/usr/local/mysql这里选择下载5.7.29的ubuntu版本注意是amd64不是arm64,或者执行下面命令wgethttps://downloads.mysql.com/archives/get/p/23/file/mysql-server_5.7.29-1ubuntu18.04_amd64.deb-bundle.tar1解压下载下......
  • mysql8.0索引数据结构
    1、为什么使用索引假如给数据使用二叉树这样的数据结构进行存储,如下图所示2、索引及其优缺点2.1、索引概述2.2、优点(1)类似大学图书馆建书目索引,提高数据检索的效率,降低数据库的IO成本,这也是创建索引最主要的原因。(2)通过创建唯一索引,可以保证数据库表中每一行数据的唯一性......
  • 无涯教程-SQLite - 连接Perl
    在本章中,您将学习如何在Perl程序中使用SQLite。安装可以使用PerlDBI模块将SQLite3与Perl集成,该模块是Perl编程语言的数据库访问模块。它定义了一组提供标准数据库接口的方法,变量和约定。以下是在Linux/UNIX计算机上安装DBI模块的简单步骤-$wgethttp://search.cpan.org/CPAN......
  • python ssh连接mysql
    fromsshtunnelimportSSHTunnelForwarderimportpymysqlclassMySqlSSH:def__init__(self):self.server=SSHTunnelForwarder(ssh_address_or_host=('13.229.92.6',22),#sshhostssh_username='lenox......
  • mysql 被删除如何恢复
    恢复ibd使用-------OnDebian/Ubuntu/LinuxMint-------$sudoapt-getinstalltestdisk-------OnCentOS/RHEL/Fedora-------$sudoyuminstalltestdisk-------OnFedora22+-------$sudodnfinstalltestdisk-------OnArchLinux-------$pacman-Ste......