• (转)SQL的书写顺序和执行顺序


    原文:https://zhuanlan.zhihu.com/p/77847158

    主要是SQL的书写顺序和执行顺序

    执行顺序

    (8) SELECT (9)DISTINCT<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_condtion>
    (10) ORDER BY<order_by_list>
    (11) LIMIT<limit_number>

    我们可以看出,SELECT子句是必选的,其它子句如WHERE子句、GROUP BY子句等是可选的。
    一个SELECT语句中,子句的顺序是固定的。必须严格按照上述的顺序书写。

    所有的查询语句都是从FROM开始执行的,在执行过程中,每个步骤都会为下一个步骤生成一个虚拟表,这个虚拟表将作为下一个执行步骤的输入。

    1. 先对FROM子句中的两个表执行一个笛卡尔乘,此时生成虚拟表 virtual table 1(选择相对小的表做基础表)
    2. 然后是应用ON条件筛选器,将ON中的逻辑表达式将应用到 virtual table 1中的各个行,筛选出满足ON中的逻辑表达式的行,生成虚拟表 virtual table 2
    3. 根据连接方式进行进一步的操作。如果是OUTER JOIN,那么这一步就将添加外部行
    • LEFT OUTER JOIN就把左表在第二步中筛选掉的行添加进来
    • RIGHT OUTER JOIN就将右表在第二步中筛选掉的行添加进来 这样生成虚拟表 virtual table 3

    如果 FROM子句中的表数目大于2,那么就将virtual table 3和第三个表连接从而计算笛卡尔积,生成虚拟表,该过程就是一个重复1-3的步骤,最终得到一个新的虚拟表virtual table 3

      1. 应用WHERE筛选器,对上一步生产的virtual table 3用WHERE筛选器筛选,生成虚拟表virtual table 4
        在这有个比较重要的细节需要提一下,如果我们有一个condition需要去筛选,应该在在ON条件筛选器还是用WHERE筛选器指定condition逻辑表达式呢?
        ON和WHERE的最大区别在于,如果在ON应用逻辑表达式那么在第三步OUTER JOIN中还可以把移除的行再次添加回来,而WHERE的移除的不可挽回的
      2. GROUP BY子句将具有相同属性的row组合成为一组,得到虚拟表virtual table 5
        如果应用了GROUP BY,那么后面的所有步骤都只能得到的virtual table 5的列或者是聚合函数,并且分组的时候是将列中唯一的值分成一组,同时只为每一组返回一行记录,这一点请牢记。
      3. 应用CUBE或者ROLLUP选项,为virtual table 5生成超组,生成virtual table 6. 这个暂时还没了解,先放到这里吧。
      4. 应用HAVING筛选器,生成virtual table 7
        HAVING筛选器是唯一一个用来筛选组的筛选器
      5. 处理SELECT子句。将virtual table 7中的并且在Select_list中的列筛选出来,生成virtual table 8
      6. 应用DISTINCT子句,virtual table 8中移除相同的行,生成virtual table 9
        事实上如果应用了GROUP BY子句,那么DISTINCT是多余的,原因同样在于,分组的时候是将列中唯一的值分成一组,同时只为每一组返回一行记录,那么所以的记录都将是不相同的。
      7. 应用ORDER BY子句。按照order_by_condition排序virtual table 10,此时返回的一个游标,而不是虚拟表。SQL是基于集合的,集合不会预先对行进行排序,它只是成员的逻辑集合,成员的顺序是无关紧要的。对表进行排序的查询可以返回一个对象,这个对象包含特定的物理顺序的逻辑组织。这个对象就叫游标。正因为返回值是游标,那么使用ORDER BY子句查询不能应用于表达式。
  • 相关阅读:
    ThinkPHP Model+数据库的切换使用
    关于SSD安装系统的一些设置(PE安装win 7)
    PHP实现文件下载:header
    Thinkphp 使用PHPExcel导入,栗子
    Ueditor 的使用(这里以php+ci为例)
    js获取鼠标选中的文字内容
    WNMP 下 Nginx 配置 (使用了phpfind一键安装环境)
    javascript 实现 trim
    javascript 获取 CSS 样式表属性
    javascript 删除节点问题
  • 原文地址:https://www.cnblogs.com/liujiacai/p/15418754.html
Copyright © 2020-2023  润新知