sql执行顺序

基础版,未考虑性能优化而做出的改变
sql执行顺序
(1)from
(2) on
(3) join
(4) where
(5)group by
(6) avg,sum....
(7)having
(8) select
(9) distinct
(10) order by

整个流程

  • 1 from:
  • from子句中的前两个表执行一个笛卡尔乘积,此时生成虚拟表table_1

    Table A Table B
    ID ID
    1 3
    2 4
    笛卡尔乘积后:
    AID BID
    1 3
    1 4
    2 3
    2 4

  • 2 on筛选器:
  • on中的逻辑表达式将应用到 vt1 中的各个行,筛选出满足on逻辑表达式的行,生成虚拟表 table_2

  • 3 join:
  • 根据join语句中多个表之间字段的联系,生成一个新的表table_3
    几种用法:
    INNER JOIN(内连接,或等值连接):取得两个表中存在连接匹配关系的记录。
    LEFT JOIN(左连接):取得左表(table1)完全记录,即是右表(table2)并无对应匹配记录。
    RIGHT JOIN(右连接):与 LEFT JOIN 相反,取得右表(table2)完全记录,即是左表(table1)并无匹配对应记录。

    Table A Table B
    ID Name ID Name
    1 aa 1 bb
    2 bb 2 cc
    3 cc 3 dd
    4 dd 4 ee

    inner join: select * from A inner join B on A.name = B.name;

    ID Name ID Name
    2 bb 1 bb
    3 cc 2 cc
    4 dd 3 dd

    left join: select * from A left join B on A.name = B.name;

    ID Name ID Name
    1 aa Null Null
    2 bb 1 bb
    3 cc 2 cc
    4 dd 3 dd

    right join: select * from A right join B on A.name = B.name;

    ID Name ID Name
    2 bb 1 bb
    3 cc 2 cc
    4 dd 3 dd
    Null Null 4 ee

  • 4 重复1-3步骤
  • from子句中的表数目多余两个表,那么就将table_3和第三个表连接从而计算笛卡尔乘积,生成虚拟表,该过程就是一个重复1-3的步骤,最终得到一个新的虚拟表 table_3。

  • 5 where筛选器
  • 上一步生产的虚拟表引用where筛选器,生成虚拟表table_4
    在含有join操作时:on和where的一点区别:
    现有两张表A和B:都只有一个字段ID,A数据有4,B的数据有3个

    Table A Table B
    ID ID
    1 1
    2 2
    3 3
    4

    1 select A.ID as AID, B.ID as BID from A left join B ON A.ID = B.ID WHERE B.ID<3

    AID BID
    1 1
    2 2

    2 select A.ID as AID, B.ID as BID from A left join B ON A.ID = B.ID AND B.ID<3

    AID BID
    1 1
    2 2
    3 Null
    4 Null

    原因: 优先级: on > left join > where
    第一条语句的顺序:
    a)执行leftjoin A left join B结果:
    AID BID
    1 1
    2 2
    3 Null
    4 Null

    b)执行where B.ID < 2结果: AID BID 1 1 2 2 第二条语句的顺序: a)先执行 A.ID = B.ID and B.ID < 2,得到结果 ID 1 2 b)再执行left join,得到结果 AID BID 1 1 2 2 3 Null 4 Null

  • 6 group by
  • group by 子句将中的唯一的值组合成为一组,得到虚拟表table_5。
    根据“By”指定的规则对数据进行分组,所谓的分组就是将一个“数据集”划分成若干个“小区域”,然后针对若干个“小区域”进行数据处理。
    Table A
    ID Level
    1 A
    2 A
    3 B
    4 B
    5 B
    6 B
    7 C

    Select count(ID) as Num ,Level from table group by Level

    table
    Num Level
    2 A
    4 B
    1 C

  • 7 having
  • 应用having筛选器,生成table_6。having筛选器是第一个也是为唯一一个应用到已分组数据的筛选器。
    如在6中针对筛选的结果需要进行Num>2的筛选:只能通过having,而不能通过where
    Where的执行在group by之前,不能够针对group 不要生成的table进行操作,因此,需要对group by后生成的table进行操作可以使用having对数据进行筛选

  • 8 select
  • 处理select子句。将table_6中的在select中出现的列筛选出来。生成table_7
    注意:由此可以看出,select是在from之后被执行的,所以在select中使用的别名在where中是不可以被使用的。

  • 9 distinct
  • 应用distinct子句,table_7中移除相同的行,生成table_8。事实上如果应用了group by子句那么distinct是多余的,
    原因同样在于,分组的时候是将列中唯一的值分成一组,同时只为每一组返回一行记录,那么所以的记录都将是不相同的。

  • 10 order by
  • 应用order by子句。按照order by 的条件去排序table_8

  • 11 返回结果

发表评论