select Distinct CRCTL1 as PolicyID 
from LifeMir.dbo.CMSUSREL A left join  LifeMir.dbo.NBSPCNTR B
On A.CRCTL1=B.PCPOLN
where  (CRALPH ='OW1' or (CRALPH='INS' and CRCTL2=0))------(59650 行受影响)
0100000001
0100000005
0100000006
0100000029
0100001001
0100001002
0100001003
..........
select Distinct CRCTL1 as PolicyID 
from LifeMir.dbo.CMSUSREL A left join  LifeMir.dbo.NBSPCNTR B
ON  A.CRCTL1=B.PCPOLN 
            and (CRALPH ='OW1' or (CRALPH='INS' and CRCTL2=0))
----(69245 行受影响)
          -----这是空数据
0000000001
0000000002
0000000003 
0000000004
0000000005 
0000000006        
..........
为什么差别有这么大呢? 这两条语句哪种是标准写法。这两条语句都代表什么意思? 谢谢

解决方案 »

  1.   

    都是符合标准的写法。LZ可以看看执行计划。理解一下left join  on 和where 的差别。
      

  2.   

    sql中语句的执行有先后顺序的,先执行on后执行where
      

  3.   

    我觉得应该是和执行顺序有关系吧,
    第一个是先执行On 然后 left join 最后才是where第二个是先执行on and  然后 left join 
      

  4.   

    /*
    标题:SQL中on条件与where条件的区别
    作者:爱新觉罗·毓华 
    时间:2008-07-14
    地点:新疆乌鲁木齐
    */数据库在通过连接两张或多张表来返回记录时,都会生成一张中间的临时表,然后再将这张临时表返回给用户。 
    在使用left jion时,on和where条件的区别如下:1、on条件是在生成临时表时使用的条件,它不管on中的条件是否为真,都会返回左边表中的记录。2、where条件是在临时表生成好后,再对临时表进行过滤的条件。这时已经没有left join的含义(必须返回左边表的记录)了,条件不为真的就全部过滤掉。假设有两张表:表1:tab1 
    id size 
    1  10 
    2  20 
    3  30 
    表2:tab2 
    size name 
    10   AAA 
    20   BBB 
    20   CCC 两条SQL:
    1、select * from tab1 left join tab2 on tab1.size = tab2.size where tab2.name='AAA'
    2、select * from tab1 left join tab2 on tab1.size = tab2.size and tab2.name='AAA'第一条SQL的过程:
    1、中间表
    on条件: 
    tab1.size = tab2.size 
    tab1.id tab1.size tab2.size tab2.name 
    1 10 10 AAA 
    2 20 20 BBB 
    2 20 20 CCC 
    3 30 (null) (null) 
    2、再对中间表过滤
    where 条件:
    tab2.name='AAA'
    tab1.id tab1.size tab2.size tab2.name 
    1 10 10 AAA 第二条SQL的过程:
    1、中间表
    on条件: 
    tab1.size = tab2.size and tab2.name='AAA'
    (条件不为真也会返回左表中的记录) tab1.id tab1.size tab2.size tab2.name 
    1 10 10 AAA 
    2 20 (null) (null) 
    3 30 (null) (null) 
     
    其实以上结果的关键原因就是left join,right join,full join的特殊性,
    不管on上的条件是否为真都会返回left或right表中的记录,full则具有left和right的特性的并集。 
    而inner jion没这个特殊性,则条件放在on中和where中,返回的结果集是相同的。
      

  5.   

    on是连接条件, where是过滤条件。对内连接来说, 二者等价。对外连接来说,
        on影响侧输入的输出, 合连接条件则输出相应列值,不合则输出null, 对主输入无影响。
        where影响结果集。
    select * from ta a left join tb on a.id=b.id and b.n is null
    此语句输出a表所有行,对于b表的列,当id=a.id且n为null时才会有输出。select * from ta a left join tb on a.id=b.id where b.n is null
    只有b.n为null的行,且a表中存在id=b.id时,才输出,符则a表的行也被过滤
      

  6.   

    on和where有区别的
    on是对两表的笛卡尔乘积做过滤
    where是对上面的结果,然后根据join的类型(left join会把左表空记录加上)最后得出来的临时表做过滤
    inner join时,如果不用having all, on和where是没有区别
      

  7.   

    没有了,我的理解是,
    如果 on条件是在生成临时表时使用的条件,它不管on中的条件是否为真,都会返回左边表中的记录。那么我认为就要比第二种执行的
    where条件是在临时表生成好后,再对临时表进行过滤的条件。这时已经没有left join的含义(必须返回左边表的记录)了,条件不为真的就全部过滤掉更快些但是我看来一下执行时间:
    (ON )
    SQL Server 执行时间:
       CPU 时间 = 312 毫秒,占用时间 = 520 毫秒。
    (where)SQL Server 执行时间:
       CPU 时间 = 282 毫秒,占用时间 = 432 毫秒。
    两者差距,难道我的分析不对吗? 
      

  8.   


    --这样看更明确
    select * from (select Distinct CRCTL1 as PolicyID  
    from LifeMir.dbo.CMSUSREL A left join LifeMir.dbo.NBSPCNTR B
    On A.CRCTL1=B.PCPOLN) tmp
    where (CRALPH ='OW1' or (CRALPH='INS' and CRCTL2=0))
    select Distinct CRCTL1 as PolicyID  
    from LifeMir.dbo.CMSUSREL A left join LifeMir.dbo.NBSPCNTR B
    ON (A.CRCTL1=B.PCPOLN and (CRALPH ='OW1' or (CRALPH='INS' and CRCTL2=0))) 
      

  9.   

    既然你知道区别了, 知道left join时on和where的意义是不一样的, 即于二个实现不同功能的东西,比较效率有意义吗
      

  10.   

    限制的对象不同第一个是先执行On 然后 left join 最后才是where  第二个是先执行on and 然后 left join  on是限制链接时候的条件
    where 是对结果进行筛选。所以又不同的结果
      

  11.   

    对于 on 和 where 外连的结果是不一样的,根据你的需求选择,无法比较效率。
      

  12.   

    简单的说on使用的时机比where早,但是这种差别只局限在外连接时候。如果是内连接那么on和where都是一样的。
      

  13.   

    --#1. ON 和 WHERE 在 INNER JOIN时无差别。在LEFT,RIGHT,FULL JOIN时有区别。
    --#2. INNER JOIN比OUTER JOIN效率高,但用哪个是根据业务逻辑而定。
    --#3. 楼主可参考一下<SQL SERVER技术内幕 T-SQL查询>第一章,里面对这个问题说明的很清晰。
      

  14.   


    ON一般与left,right,full,join,连用时有与Where区别。
    inner on == Where
      

  15.   


    标题:SQL中on条件与where条件的区别
    作者:爱新觉罗·毓华 
    时间:2008-07-14
    地点:新疆乌鲁木齐
    */数据库在通过连接两张或多张表来返回记录时,都会生成一张中间的临时表,然后再将这张临时表返回给用户。 
    在使用left jion时,on和where条件的区别如下:1、on条件是在生成临时表时使用的条件,它不管on中的条件是否为真,都会返回左边表中的记录。2、where条件是在临时表生成好后,再对临时表进行过滤的条件。这时已经没有left join的含义(必须返回左边表的记录)了,条件不为真的就全部过滤掉。假设有两张表:表1:tab1 
    id size 
    1  10 
    2  20 
    3  30 
    表2:tab2 
    size name 
    10   AAA 
    20   BBB 
    20   CCC 两条SQL:
    1、select * from tab1 left join tab2 on tab1.size = tab2.size where tab2.name='AAA'
    2、select * from tab1 left join tab2 on tab1.size = tab2.size and tab2.name='AAA'第一条SQL的过程:
    1、中间表
    on条件: 
    tab1.size = tab2.size 
    tab1.id tab1.size tab2.size tab2.name 
    1 10 10 AAA 
    2 20 20 BBB 
    2 20 20 CCC 
    3 30 (null) (null) 
    2、再对中间表过滤
    where 条件:
    tab2.name='AAA'
    tab1.id tab1.size tab2.size tab2.name 
    1 10 10 AAA 第二条SQL的过程:
    1、中间表
    on条件: 
    tab1.size = tab2.size and tab2.name='AAA'
    (条件不为真也会返回左表中的记录) tab1.id tab1.size tab2.size tab2.name 
    1 10 10 AAA 
    2 20 (null) (null) 
    3 30 (null) (null) 
     
    其实以上结果的关键原因就是left join,right join,full join的特殊性,
    不管on上的条件是否为真都会返回left或right表中的记录,full则具有left和right的特性的并集。 
    而inner jion没这个特殊性,则条件放在on中和where中,返回的结果集是相同的。
      

  16.   


    /*
    on是连接条件, where是过滤条件。对内连接来说, 二者等价。对外连接来说,
      on影响侧输入的输出, 合连接条件则输出相应列值,不合则输出null, 对主输入无影响。
      where影响结果集。
    */select * from ta a left join tb on a.id=b.id and b.n is null
    --此语句输出a表所有行,对于b表的列,当id=a.id且n为null时才会有输出。select * from ta a left join tb on a.id=b.id where b.n is null
    --只有b.n为null的行,且a表中存在id=b.id时,才输出,符则a表的行也被过滤
    +1
      

  17.   

    on 和 where 完全不以样啊,on 是连接条件, where是过滤条件。这两个完全不一样,不能混淆的。如果你要查询A,B表,select * from A,B where A.ID=B.ID ,如果你是用的内连接,那么where可以代替on,但是on绝对不能代替where。