sql查询执行顺序
所有的执行语句顺序都会产生一个虚拟表,后面的执行语句执行完再产生一个虚拟表,最后执行完的结果即是我们所需要的记录
(1)from
所有的查询语句都是从from开始执行,会对要查询的表做一个交叉连接(全连接),生成一个笛卡尔结果集。
如果是单表查询,则是表的本身
(2)on
on 是join的条件,即是用来进行多表连接时所限定的条件,所以可以用来过滤(1)所产生的笛卡尔积结果。
(3)join
join是用来说明限定表于表之间的连接方式,有内链接,外链接,内链接分为等值链接和自然链接(=,<,>)。
外链接又分为左外链接,右外链接,外部全联接(left join, right join, full join)。默认是内部连接。
on和where的最大区别在于,如果在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:
(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行。