码迷,mamicode.com
首页 > 其他好文 > 详细

连接查询时on与where的区别

时间:2015-01-18 22:39:04      阅读:1187      评论:0      收藏:0      [点我收藏+]

标签:

写在前面:在编写SQL的过程中,我经常使用LEFT JOIN关联多个小查询形成一个大查询,产生一张宽表。在进行这些查询中,给我感触最深的亮点是:1、left join中主表的选择,主表的选择很重要,否则就会漏掉一些记录或者ID;2、连接查询的ON条件和外层的WHERE条件的区分使用,如果对他们的作用以及区别有一个很清晰的认识,那么用混一条语句就可能产生很大的差别。因此,本文在学习了网友的博文的基础上进行如下总结和整理。

 

关键点:数据库在通过连接两张或多张表来返回记录时,都会生成一张中间的临时表,然后再将这张临时表返回给用户。

1、在使用left jion时,on和where条件的区别:

(1)on条件是在生成临时表时使用的条件,它不管on中的条件是否为真,都会返回左边表中的记录。

(2)where条件是在临时表生成好后,再对临时表进行过滤的条件。这时已经没有left join的含义(必须返回左边表的记录)了,条件不为真的就全部过滤掉。

举例:假设有两张表:

表1:tab2

id

size

1

10

2

20

3

30

 

 

 

 

 

 

表2:tab2

size

name

10

AAA

20

BBB

20

CCC


 

 

 

 

 

两条SQL:
1、select * form tab1 left join tab2 on (tab1.size = tab2.size) where tab2.name=’AAA’
2、select * form 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)

    

 

 

 

 

 

 

 

 

比较上面两个SQL运行的结果可以发现:对于left join连接查询,左边的表作为主表,不管是否满足on条件,都会返回每条记录。这一点是连接查询(left/right/full join)的特殊性所在。因此,对于多个on条件的连接查询,我们可以换一种思路理解,即这些on条件先对次表进行筛选过滤,然后将过滤的结果和主表进行匹配关联(这种匹配也是基于on条件的匹配,比如tab1.size = tab2.size)。而on后面的where是对条件关联后的临时表从整体上进行条件筛选。

2、on、where、having的区别:

在SQL语句中,on、where、having这三个是都可以加条件的子句。执行顺序是:on是最先执行,where次之,having最后。on在做连接查询时使用,having在分组统计时使用(即前提要使用group by),where想用就用。

3、几种连接查询:

交叉连接:cross join,指将两张表或者多张表的所有记录进行所有可能的组合。如,table1有m条记录,table2有n条记录,table1 inner join table2产生的临时表就有m*n条记录。本质上相当于笛卡尔积。等价于from table1,table2。

内连接:inner join,在T-SQL中又分为等值连接,自然连接,自连接,其中自然连接、和自连接都是等值连接的特殊情况。内连接均可转化为from table1,table2,…形式。

 外连接:左外(left join)、右外(right join)、全外(full join)。右外连接操作一般转换为左外连接使用。左外连接左表时主表,保留主表所有记录,右表作为词表进行条件匹配。全外连接,左右都是主表,每条记录都保留,对于不能匹配的记录的字段用NULL替代。

 4、如果我们把连接条件on放在了where后面,那么所有的left,right,等这些操作将不起任何作用,对于这种情况,它的效果就完全等同于inner连接。如:

select * form tab1 left join tab2 on (tab1.size = tab2.size)

select * form tab1 left join tab2 where (tab1.size = tab2.size)

第一个SQL中进行的左连接查询,按size字段进行匹配,保留全部tab1记录;第二个SQL中left join不起作用的,实质是inner join,连接产生临时表后,再使用where条件进行筛选。

 

参考资料:

[1]on条件与where条件的区别

感谢!

文中如有错误和描述不当,欢迎指正!

 

连接查询时on与where的区别

标签:

原文地址:http://www.cnblogs.com/hbsygfz/p/4232344.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!