SQL 语句的执行顺序

216 阅读4分钟

sql查询执行顺序

所有的执行语句顺序都会产生一个虚拟表,后面的执行语句执行完再产生一个虚拟表,最后执行完的结果即是我们所需要的记录

(1)from

所有的查询语句都是从from开始执行,会对要查询的表做一个交叉连接(全连接),生成一个笛卡尔结果集。
如果是单表查询,则是表的本身

(2)on

onjoin的条件,即是用来进行多表连接时所限定的条件,所以可以用来过滤(1)所产生的笛卡尔积结果。

(3)join

join是用来说明限定表于表之间的连接方式,有内链接,外链接,内链接分为等值链接和自然链接(=<,>)。
外链接又分为左外链接,右外链接,外部全联接(left join, right join, full join)。默认是内部连接。
onwhere的最大区别在于,如果在on应用[逻辑表达式])那么在第三步outer join中还可以把移除的行再次添加回来,
而where的移除的最终的。join会补充外部链接被过滤掉的记录,即会填充那些主表为null的记录。
  a表         id   name         b表     id    job   parent_id  
              1   张3                   1     23     1  
              2   李四                  2     34     2  
              3   王武                  3     34     4
              
              
  select   a.*,b.*   from   a   left   join   b     on   a.id=b.parent_id  
  结果是    
  1   张3                   1     23     1  
  2   李四                  2     34     2  
  3   王武                  null

第三条记录即是在join的时候补充回来的。但where过滤了就过滤了,不会再补充

(4)where

应用where筛选器,对上一步生产的虚拟表引用where筛选器,生成虚拟表。注意where和on的区别,这就是为什么where要在on后面执行。

(5)group by

子句将中的相同的列值组合成为一组,例如下面实例中的site_id,得到虚拟表vt5。如果应用了group by,那么后面的所有步骤都只能得到的vt5的列或者是聚合函数(count、sum、avg等)。因为所有的记录都被分为同一组,所以只能在这基础上查询了,等于说记录被聚合了,被分成一块一块了,不是一条一条了,所以不能查到单条记录了,只能查一块一块的。

FROM table_name
WHERE column_name operator value
GROUP BY column_name;
+-----+---------+-------+------------+
| aid | site_id | count | date       |
+-----+---------+-------+------------+
|   1 |       1 |    45 | 2016-05-10 |
|   2 |       3 |   100 | 2016-05-13 |
|   3 |       1 |   230 | 2016-05-14 |
|   4 |       2 |    10 | 2016-05-14 |
|   5 |       5 |   205 | 2016-05-14 |
|   6 |       4 |    13 | 2016-05-15 |
|   7 |       3 |   220 | 2016-05-15 |
|   8 |       5 |   545 | 2016-05-16 |
|   9 |       3 |   201 | 2016-05-17 |
+-----+---------+-------+------------+

eg:SELECT site_id, SUM(access_log.count) AS nums\
FROM access_log GROUP BY site_id;
数据来自[https://www.runoob.com/sql/sql-groupby.html](url)

the result: image.png

(6)having

having筛选器是第一个也是为唯一一个应用到已分组数据的筛选器。在 SQL 中增加 HAVING 子句原因是,WHERE 关键字无法与聚合函数一起使用。HAVING 子句可以让我们筛选分组后的各组数据。

SELECT Websites.name, Websites.url, SUM(access_log.count) AS nums 
FROM (access_log INNER JOIN Websites ON access_log.site_id=Websites.id) 
GROUP BY Websites.name 
HAVING SUM(access_log.count) > 200;

(7)select

选择满足上述所有条件的记录

(8)distinct

应用distinct子句,移除相同的记录,只保留一行。 如果应用了group by子句那么distinct是多余的,原因同样在于,分组的时候是将列中唯一的值分成一组,同时只为每一组返回一行记录,那么所以的记录都将是不相同的,同样在是用于union 进行两个查询合并时会自动去重,union all 则会展示全部数据不会经进行去重。如果需要不展示出重复数据时使用group by , distinct 或union 视情况而定。

(9)order by

by子句。按照order_by_condition排序vt9,此时返回的一个游标,而不是虚拟表。sql是基于集合的理论的,集合不会预先对他的行排序,它只是成员的逻辑集合,成员的顺序是无关紧要的。对表进行排序的查询可以返回一个对象,这个对象包含特定的物理顺序的逻辑组织。这个对象就叫游标。正因为返回值是游标,那么使用order
by 子句查询不能应用于表表达式。排序是很需要成本,消耗性能,除非必须要排序,否则最好不要指定order
by,最后,在这一步中是第一个也是唯一一个可以使用select列表中别名的步骤。

(10)limit or top

返回所查询结果的前n行记录,或者分页(limit),每页n行。

参考:zhuanlan.zhihu.com/p/34057032

www.runoob.com/sql/sql-hav…