标签:
写在前面:在编写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的过程:
|
第二条SQL的过程:
|
比较上面两个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条件进行筛选。
参考资料:
感谢!
文中如有错误和描述不当,欢迎指正!
标签:
原文地址:http://www.cnblogs.com/hbsygfz/p/4232344.html