SQL逻辑语句执行顺序

一、select语句关键字的定义的顺序、执行顺序  

  select

  distinct <select_list>

  from <left_table>

  <join_type> join <right_table>

  on <join_condition>

  where <where_condition>

  group by <group_by list>

  having <having_condition>

  order by <order_by_condition>

  limit <limit_number>

二、准备表和数据

1.新建一个测试数据库testDB

  create datebase testDB

2.创建测试表table1和table2、

  create table table1

  (

   customer_id verther (10) not null,

   city verther (10) not null,

   primary key (customer_id),

   )enging=innoDB default charset=utf8;

 create table table2

   (

     order_id int not null auto_increment,

     customer_id verther (10) ,
     primary key (order_id),

   )enging=innoDB default charset=utf8

3.插入测试数据

    insert into table1 (customer_id,city)values (a,shanghai)

    insert into table2  (customer_id) values (a)

三、SQL逻辑查询测试语句

  查询来自‘上海’且订单少于2的客户

  select a.customer_id, count(b.order_id) as total_orders

  from table as a

  left join table2 as b

  on a.customer_id=b.customer_id

  where a.city='shanghai'

  group by a.customer_id

  having count(b.order_id)<2

  order by total_orders DESC

四、执行顺序分析

  在这些SQL语句执行的过程中,都会产生一个虚拟表,用来储存SQL语句的执行结果(这是重点),根据这个虚拟变化表,得到最终查询结果的过程,来分析整个SQL逻辑查询的执行顺序和过程。

 1. 执行from语句

  第一步执行from语句对两张表执行笛卡尔积,得到一张虚拟表。接下来在虚拟表上执行

 2. 执行on过滤

  执行from语句后,接着就执行on过滤,去掉不符合条件的数据得到表2,接下来在表2上来执行

 3. 添加外部行

  这一步只有在连接类型为 outer join 才会执行 ,例如:left outer join 、right outer join 、full outer join。大多数情况下会省略掉outer关键字,但outer表示外部行

  添加外部行的工作就是在表2 的基础上添加保留表中被过滤条件过滤掉的数据,非保留表中的数据被赋予null值,最后生成虑拟表3,接下来在表3上执行

 4. 执行where过滤

  在表3上执行where过滤,只有符合<where_condition>的记录才会输出到虚拟表4

  注意:1.由于数据还没有分组,还不能在where中对分组统计过滤

     2.由于还没有进行列的选取操作,在select中也不能使用列的别名

  5.    执行group by 分组

      group by 主要对使用where子语句得到的虚拟表进行分组操作,得到虚拟表5

  6.   执行having过滤

   having 子句和group by 子句配合使用,对虚拟表5进行条件过滤,得到虚拟表6

   7.   执行select列表

   select写在第一句,但并不会先执行,执行select中的测试语句,进行筛选到我们想要的值得到表7

   8.   执行distinct 子句

    如果在查询中指定了distinct子句,则会创建一张内存临时表(如果内存放不下,则就会放在磁盘里)。这张临时表的表结构和产生的表7的表结构一样,不同的是对dintinct操作的列增加

   了一个唯一索引,以此来去除重复数据

     执行order by 语句 

     对虚拟表中的内容按照指定的列进行排序,然后返回一张新的虚拟表,就会储存在虚拟表8中

  9.   执行limit 语句

     limit子句从上述操作得到表8中选出从指定位置开始的指定行数据;对于没有应用order by的limit子句得到结果同样是无序的,所以通常情况下我们一般看到limit 和order by 一起使用。

  

  

  

   

原文地址:https://www.cnblogs.com/jacky912/p/10320557.html