Sql基础篇

- 背景:不同于传统程序的顺序执行流程,初中级的developer通常对于SQL的的具体执行逻辑、顺序感到困惑,基本刚入门的后端程序员都有类似的问题,对与程序(SQL)的具体执行流程有一个清晰的执行流程是一个合格程序员必备的技能,下面对与SQL的执行顺序做一个基本的介绍,

注意下面介绍的是SQL执行的逻辑顺序,目的是帮助大家认识清楚SQL的基础的执行流程,此处暂不涉及任何索引的相关的内容

下文所有的示例均基于MySql进行讲解,此处不涉及到各个数据库特有的功能(rollup/cube等,分页例外,毕竟每个数据库(Mysql/oracle/sqlserver)对与分页的语法不一样,而分页是一个非常常用的功能)

  • SQL执行顺序(逻辑顺序)

    1
    2
    3
    4
    5
    6
    7
    8
    
      (7) SELECT (8)DISTINCT<Select_field_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) HAVING<having_condtion>
      (9) ORDER BY<order_by_list>
      (10) LIMIT<limit_number>
    
    • 步骤1:From后面的字句通常是第一步,目的是在系统中定位到具体的表/试图,不存在此处直接抛出异常,对与left_table与right_table做笛卡尔积,生成一个基础的表vt1(virtual_table1)
    • 步骤2:on 条件,left 与right关联关系的条件列,将on中的逻辑表达式应用于vt1的各个行,得到vt2
    • 步骤3:join 根据join_type的类型,做对应的处理,此处会添加额外的行
      • left (out) join ,left_table作为保留表,将第2步中过滤的行添加进来
      • right(out) join,right_table作为保留表,同样将第2步中过滤的行添加进来

      生成vt3,如果from谓词后面的表多余2个,将vt3继续与后面的表做链接,重复上述三个步骤,得到最终的vt3

    • 步骤4:对vt3应用where筛选条件,得到vt4,对与inner join,on 和where的条件并无区别,对与outer join,此处就需要注意了,由于步骤3会基于保留表(取决于join类型)添加额外的行,所以on条件中的过滤会被添加回来来,而针对于where子句中的条件过滤,是对最终结果集的过滤,此处的筛选移除是无法被添加进来
    • 步骤5:group by 子句针对vt4,应用具体的分组条件,通俗点就是将group by后拥有相同行内容的数据进行规整(count/max/min/avg等),得到vt5
    • 步骤6:基于vt5应用having子句(可以简单理解为进一步的where筛选,通常是基于分组函数的值进行过滤),针对vt5的结果集做进一步的过滤,得到vt6
    • 步骤7:基于vt6,执行select语句,取出具体的数据列,得到vt7
    • 步骤8:基于vt7执行distinct,对结果集进行去重,得到vt8
    • 步骤9:基于vt8,执行具体的排序操作,生成vt9
    • 步骤10:基于vt9,执行具体的分页操作,生成vt10,vt10即为最终的结果集,返回给调用方