精华内容
下载资源
问答
  • SQL执行顺序

    2017-10-16 22:10:36
    sql执行顺序

    sql语句作为结构化查询语言,从语法构成和逻辑上相对简单明了,简单举例基本语法样式:

    select ——[column]
    from ——-[table]
    where ——-[检索条件]
    group by ——[将数据按组划分]
    having ——-[分组过滤条件]
    order by——-[将数据进行排序]

    标准的SQL语句的执行顺序:
    1、首先执行from子句,如果from后有多个table,先组装不同的数据源到临时表T1;
    2、根据where后的条件对临时表T1进行筛选过滤,生成临时表T2;
    3、按照group by *对临时表T2的数据进行分组,分组后生成临时表T3;【如果没有用到聚合函数,当然也可以不分组】
    4、如果有having子句,接下来按照子句条件过滤临时表T3的数据,再生成临时表T4;
    5、执行select,按照select所选择的列(column)对临时表T4进行过滤,先执行聚合函数,然后执行distinct去重复行,过滤后生成临时表T5;【如果select后用到聚合函数,则先进行计算。聚合函数也就是sum,count,avg,min,max等函数。】
    6、order by ,按照order by 条件指定列对临时表T5的数据进行升序或者降序(ASC为升序,DESC为降序,默认为升序)排序后生成临时表T6;
    7、top,按照top的条件从临时表T6中拉出对应数据,生成临时表T7,并把数据呈现给用户。【top命令不是所有数据库都支持的】

    展开全文
  • sql执行顺序

    2019-07-12 11:32:10
    sql中执行顺序一、sql执行顺序二、mysql的执行顺序 一、sql执行顺序 (1)from (3) join (2) on (4) where (5)group by(开始使用select中的别名,后面的语句中都可以使用) (6) avg,sum… (7)having (8) select (9) ...

    一、sql执行顺序

    (1)from
    (3) join
    (2) on
    (4) where
    (5)group by(开始使用select中的别名,后面的语句中都可以使用)
    (6) avg,sum…
    (7)having
    (8) select
    (9) distinct
    (10) order by

    从这个顺序中我们不难发现,所有的 查询语句都是从from开始执行的,在执行过程中,每个步骤都会为下一个步骤生成一个虚拟表,这个虚拟表将作为下一个执行步骤的输入。
    第一步:首先对from子句中的前两个表执行一个笛卡尔乘积,此时生成虚拟表 vt1(选择相对小的表做基础表)
    第二步:接下来便是应用on筛选器,on 中的逻辑表达式将应用到 vt1 中的各个行,筛选出满足on逻辑表达式的行,生成虚拟表 vt2
    第三步:如果是outer join 那么这一步就将添加外部行,left outer jion 就把左表在第二步中过滤的添加进来,如果是right outer join 那么就将右表在第二步中过滤掉的行添加进来,这样生成虚拟表 vt3
    第四步:如果 from 子句中的表数目多余两个表,那么就将vt3和第三个表连接从而计算笛卡尔乘积,生成虚拟表,该过程就是一个重复1-3的步骤,最终得到一个新的虚拟表 vt3。
    第五步:应用where筛选器,对上一步生产的虚拟表引用where筛选器,生成虚拟表vt4,在这有个比较重要的细节不得不说一下,对于包含outer join子句的查询,就有一个让人感到困惑的问题,到底在on筛选器还是用where筛选器指定逻辑表达式呢?on和where的最大区别在于,如果在on应用逻辑表达式那么在第三步outer join中还可以把移除的行再次添加回来,而where的移除的最终的。举个简单的例子,有一个学生表(班级,姓名)和一个成绩表(姓名,成绩),我现在需要返回一个x班级的全体同学的成绩,但是这个班级有几个学生缺考,也就是说在成绩表中没有记录。为了得到我们预期的结果我们就需要在on子句指定学生和成绩表的关系(学生.姓名=成绩.姓名)那么我们是否发现在执行第二步的时候,对于没有参加考试的学生记录就不会出现在vt2中,因为他们被on的逻辑表达式过滤掉了,但是我们用left outer join就可以把左表(学生)中没有参加考试的学生找回来,因为我们想返回的是x班级的所有学生,如果在on中应用学生.班级='x’的话,left outer join会把x班级的所有学生记录找回(感谢网友康钦谋__康钦苗的指正),所以只能在where筛选器中应用学生.班级=‘x’ 因为它的过滤是最终的。
    第六步:group by 子句将中的唯一的值组合成为一组,得到虚拟表vt5。如果应用了group by,那么后面的所有步骤都只能得到的vt5的列或者是聚合函数(count、sum、avg等)。原因在于最终的结果集中只为每个组包含一行。这一点请牢记。
    第七步:应用cube或者rollup选项,为vt5生成超组,生成vt6.
    第八步:应用having筛选器,生成vt7。having筛选器是第一个也是为唯一一个应用到已分组数据的筛选器。
    第九步:处理select子句。将vt7中的在select中出现的列筛选出来。生成vt8.
    第十步:应用distinct子句,vt8中移除相同的行,生成vt9。事实上如果应用了group by子句那么distinct是多余的,原因同样在于,分组的时候是将列中唯一的值分成一组,同时只为每一组返回一行记录,那么所以的记录都将是不相同的。
    第十一步:应用order by子句。按照order_by_condition排序vt9,此时返回的一个游标,而不是虚拟表。sql是基于集合的理论的,集合不会预先对他的行排序,它只是成员的逻辑集合,成员的顺序是无关紧要的。对表进行排序的查询可以返回一个对象,这个对象包含特定的物理顺序的逻辑组织。这个对象就叫游标。正因为返回值是游标,那么使用order by 子句查询不能应用于表表达式。排序是很需要成本的,除非你必须要排序,否则最好不要指定order by,最后,在这一步中是第一个也是唯一一个可以使用select列表中别名的步骤。
    第十二步:应用top选项。此时才返回结果给请求者即用户。

    二、mysql的执行顺序

    SELECT语句定义
    一个完成的SELECT语句包含可选的几个子句。SELECT语句的定义如下:
    SQL代码

    <SELECT clause> [<FROM clause>] [<WHERE clause>] [<GROUP BY clause>] [<HAVING clause>] [<ORDER BY clause>] [<LIMIT clause>]   
    

    SELECT子句是必选的,其它子句如WHERE子句、GROUP BY子句等是可选的。
    一个SELECT语句中,子句的顺序是固定的。例如GROUP BY子句不会位于WHERE子句的前面。

    SELECT语句执行顺序
    SELECT语句中子句的执行顺序与SELECT语句中子句的输入顺序是不一样的,所以并不是从SELECT子句开始执行的,而是按照下面的顺序执行:
    开始->FROM子句->WHERE子句->GROUP BY子句->HAVING子句->ORDER BY子句->SELECT子句->LIMIT子句->最终结果
    每个子句执行后都会产生一个中间结果,供接下来的子句使用,如果不存在某个子句,就跳过
    对比了一下,mysql和sql执行顺序基本是一样的, 标准顺序的 SQL 语句为:

    select 考生姓名, max(总成绩) as max总成绩   
      
    from tb_Grade   
      
    where 考生姓名 is not null   
      
    group by 考生姓名   
      
    having max(总成绩) > 600   
      
    order by max总成绩   
    

    在上面的示例中 SQL 语句的执行顺序如下:

    (1). 首先执行 FROM 子句, 从 tb_Grade 表组装数据源的数据

    (2). 执行 WHERE 子句, 筛选 tb_Grade 表中所有数据不为 NULL 的数据

    (3). 执行 GROUP BY 子句, 把 tb_Grade 表按 “学生姓名” 列进行分组(注:这一步开始才可以使用select中的别名,他返回的是一个游标,而不是一个表,所以在where中不可以使用select中的别名,而having却可以使用,感谢网友 zyt1369 提出这个问题)

    (4). 计算 max() 聚集函数, 按 “总成绩” 求出总成绩中最大的一些数值

    (5). 执行 HAVING 子句, 筛选课程的总成绩大于 600 分的.

    (7). 执行 ORDER BY 子句, 把最后的结果按 “Max 成绩” 进行排序.

    展开全文
  • sql 执行顺序

    2016-09-25 16:02:00
    转自:sql执行顺序 SQL 不同于与其他编程语言的最明显特征是处理代码的顺序。在大数编程语言中,代码按编码顺序被处理,但是在SQL语言中,第一个被处理的子句是FROM子句,尽管SELECT语句第一个出现,但是几乎总是...

    sql 执行顺序

    2016-09-25

    转自:sql执行顺序 

    SQL 不同于与其他编程语言的最明显特征是处理代码的顺序。在大数编程语言中,代码按编码顺序被处理,但是在SQL语言中,第一个被处理的子句是FROM子句,尽管SELECT语句第一个出现,但是几乎总是最后被处理。 

    每个步骤都会产生一个虚拟表,该虚拟表被用作下一个步骤的输入。这些虚拟表对调用者(客户端应用程序或者外部查询)不可用。只是最后一步生成的表才会返回 给调用者。如果没有在查询中指定某一子句,将跳过相应的步骤。下面是对应用于SQL server 2000和SQL Server 2005的各个逻辑步骤的简单描述。

    (8)SELECT (9)DISTINCT  (11)<Top Num> <select list>
    (1)FROM [left_table]
    (3)<join_type> JOIN <right_table>
    (2)ON <join_condition>
    (4)WHERE <where_condition>
    (5)GROUP BY <group_by_list>
    (6)WITH <CUBE | RollUP>
    (7)HAVING <having_condition>
    (10)ORDER BY <order_by_list>

    逻辑查询处理阶段简介

    1. FROM:对FROM子句中的前两个表执行笛卡尔积(Cartesian product)(交叉联接),生成虚拟表VT1
    2. ON:对VT1应用ON筛选器。只有那些使<join_condition>为真的行才被插入VT2。
    3. OUTER(JOIN):如 果指定了OUTER JOIN(相对于CROSS JOIN 或(INNER JOIN),保留表(preserved table:左外部联接把左表标记为保留表,右外部联接把右表标记为保留表,完全外部联接把两个表都标记为保留表)中未找到匹配的行将作为外部行添加到 VT2,生成VT3.如果FROM子句包含两个以上的表,则对上一个联接生成的结果表和下一个表重复执行步骤1到步骤3,直到处理完所有的表为止。
    4. WHERE:对VT3应用WHERE筛选器。只有使<where_condition>为true的行才被插入VT4.
    5. GROUP BY:按GROUP BY子句中的列列表对VT4中的行分组,生成VT5.
    6. CUBE|ROLLUP:把超组(Suppergroups)插入VT5,生成VT6.
    7. HAVING:对VT6应用HAVING筛选器。只有使<having_condition>为true的组才会被插入VT7.
    8. SELECT:处理SELECT列表,产生VT8.
    9. DISTINCT:将重复的行从VT8中移除,产生VT9.
    10. ORDER BY:将VT9中的行按ORDER BY 子句中的列列表排序,生成游标(VC10).
    11. TOP:从VC10的开始处选择指定数量或比例的行,生成表VT11,并返回调用者。

    注:步骤10,按ORDER BY子句中的列列表排序上步返回的行,返回游标VC10.这一步是第一步也是唯一一步可以使用SELECT列表中的列别名的步骤。这一步不同于其它步骤的 是,它不返回有效的表,而是返回一个游标。SQL是基于集合理论的。集合不会预先对它的行排序,它只是成员的逻辑集合,成员的顺序无关紧要。对表进行排序 的查询可以返回一个对象,包含按特定物理顺序组织的行。ANSI把这种对象称为游标。理解这一步是正确理解SQL的基础。

    因为这一步不返回表(而是返回游标),使用了ORDER BY子句的查询不能用作表表达式。表表达式包括:视图、内联表值函数、子查询、派生表和共用表达式。它的结果必须返回给期望得到物理记录的客户端应用程序。例如,下面的派生表查询无效,并产生一个错误:

     

    select *  from(select orderid,customerid from orders order by orderid)  as d

    下面的视图也会产生错误

    create view my_view 
    as 
    select * from orders order by orderid

    在SQL中,表表达式中不允许使用带有ORDER BY子句的查询,而在T—SQL中却有一个例外(应用TOP选项)。

    所以要记住,不要为表中的行假设任何特定的顺序。换句话说,除非你确定要有序行,否则不要指定ORDER BY 子句。排序是需要成本的,SQL Server需要执行有序索引扫描或使用排序运行符。

     

    转载于:https://www.cnblogs.com/Ming8006/p/5906123.html

    展开全文

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 8,110
精华内容 3,244
关键字:

sql执行顺序