• SQL中把筛选条件放在left outer join的on 和 where 后面的区别


    SQL中把筛选条件放在left outer join的on 和 where 后面的区别

    create table [Table_1](
    [PKey] int
    ,[FKey] int
    ,[value1] int
    ,[value2] int
    )
    create table[Table_2]
    ([PKey] int
    ,[value1] int
    ,[value2] int
    )
    drop table [Table_1]
    drop table [Table_2]
    delete[Table_1]
    delete[Table_2]
    insert into [Table_1] values(1,0,21,31)
    insert into [Table_1] values(2,0,22,31)
    insert into [Table_1] values(3,0,23,31)
    insert into [Table_1] values(4,0,24,31)
    insert into [Table_1] values(5,0,21,31) --duplicate 21
    insert into [Table_1] values(6,0,25,31) --no 25 in table2
    insert into [Table_1] values(5,1,21,31) --condition table1 fkey =1

    insert into [Table_2] values(6,21,32)
    insert into [Table_2] values(7,22,32)
    insert into [Table_2] values(8,23,33) -- for seeing on and where difference
    insert into [Table_2] values(9,24,32)
    insert into [Table_2] values(10,26,32) -- no 26 in table1
    select * from [Table_1]
    select * from [Table_2]
    ----select t1.*,'|' n,t2.* from Table_1 t1
    ----inner join Table_2 t2 on t1.value1 =t2.value1
    --left outer join learning
    select t1.*,'|' n,t2.* from Table_1 t1
    left outer join Table_2 t2 on t1.value1 =t2.value1 order by t1.value1
    --part1:
    select t1.*,'|' n,t2.* from Table_2 t2
    left outer join Table_1 t1 on t1.value1 =t2.value1
    order by t1.value1

    --part2:

    select t1.*,'|' n,t2.* from Table_2 t2
    left outer join Table_1 t1 on t1.value1 =t2.value1
    where t1.fkey = 0
    order by t1.value1

    --part3:

    select t1.*,'|' n,t2.* from Table_2 t2
    left outer join Table_1 t1 on t1.fkey = 0
    and t1.value1 =t2.value1
    order by t1.value1

    left join result:

     

    自己的理解:

    part1 vs part2:join之后,对结果集进行 where筛选,所以最终结果不会有 t1.fkey = 0的行。

    part1 vs part3:join时,对table_1进行 t1.fkey = 0筛选得到虚拟table_1_2,然后table_1_2与table2进行join。

    基于理论:

    T-SQL在查询各个阶级分别干了什么:

    (1)FROM 阶段

        FROM阶段标识出查询的来源表,并处理表运算符。在涉及到联接运算的查询中(各种join),主要有以下几个步骤:

      a.求笛卡尔积。不论是什么类型的联接运算,首先都是执行交叉连接(cross join),求笛卡儿积,生成虚拟表VT1-J1。

          b.ON筛选器。这个阶段对上个步骤生成的VT1-J1进行筛选,根据ON子句中出现的谓词进行筛选,让谓词取值为true的行通过了考验,插入到VT1-J2。

          c.添加外部行。如果指定了outer join,还需要将VT1-J2中没有找到匹配的行,作为外部行添加到VT1-J2中,生成VT1-J3。

        经过以上步骤,FROM阶段就完成了。概括地讲,FROM阶段就是进行预处理的,根据提供的运算符对语句中提到的各个表进行处理(除了join,还有apply,pivot,unpivot)

    (2)WHERE阶段

         WHERE阶段是根据<where_predicate>中条件对VT1中的行进行筛选,让条件成立的行才会插入到VT2中。

    (3)GROUP BY阶段

          GROUP阶段按照指定的列名列表,将VT2中的行进行分组,生成VT3。最后每个分组只有一行。

    (4)HAVING阶段

          该阶段根据HAVING子句中出现的谓词对VT3的分组进行筛选,并将符合条件的组插入到VT4中。

    (5)SELECT阶段

      这个阶段是投影的过程,处理SELECT子句提到的元素,产生VT5。这个步骤一般按下列顺序进行

            a.计算SELECT列表中的表达式,生成VT5-1。

            b.若有DISTINCT,则删除VT5-1中的重复行,生成VT5-2

            c.若有TOP,则根据ORDER BY子句定义的逻辑顺序,从VT5-2中选择签名指定数量或者百分比的行,生成VT5-3

    (6)ORDER BY阶段

         根据ORDER BY子句中指定的列明列表,对VT5-3中的行,进行排序,生成游标VC6. 

    copy一张别人转发的图。下面是<<Inside Microsoft SQL Server 2008 T-SQL Querying>>一书中给的一幅SQL 执行顺序的插图.

  • 相关阅读:
    JAVA数据库建表工具类
    HTML加CSS3太极图demo
    MD5加密(JAVA&JS)
    Base64工具类(JAVA&JS)
    JS模拟圆周运动
    JAVA读取写入excle表兼容版
    Math.PI和Math.sin() 与 Math.cos()搭配使用详解
    MySQL8.0数据库连接问题
    echarts饼状图案例
    JS前端使用MD5加密
  • 原文地址:https://www.cnblogs.com/watermarks/p/5416835.html
Copyright © 2020-2023  润新知