SQL多表链接

来源:互联网 发布:梦想小镇知乎 编辑:程序博客网 时间:2024/06/11 22:06
链接(join)是多表(关系)数据工作的关键

只要两个表的公共字段有匹配值,就将这两个表中的记录组合起来。

大家在编程中经常遇到要在多个表中查询数据,在数据库的规范化中也经常把一个表经过投影分解成多个符合更高级范式的表。符合标准化的同时,自然要付出灵活性和性能的代价。把多个表连接在一起是一个耗时的操作,建议对那些经常用到的信息集中存放在一个表中,即使某些方面不符合规范化标准也可。多表连接操作最常用的是表和表之间取笛卡儿积(交叉链接),其他的还有Inner Join,left outer join,right outer join,full outer join,下面分别说明它们的区别。


1. 内连接 (Inner Join)
Inner Join 把两个表连接在一起,返回两个表中相匹配的记录,是2和3的交集。

2 .外链接,包括左外连接、右外连接和全外连接
2.1 Left outer join
Left outer join,左侧表所有的记录都返回,右侧匹配的记录返回,没有匹配的返回Null
2.2 Right outer join
与Left outer join相反,右侧的记录返回,左侧返回匹配的记录,没有匹配返回Null
2.3 Full outer join
2和3的并集。
3 笛卡尔积( Cross join)
两个表的笛卡儿积,返回所有可能的值,不允许有连接条件!


为了说明问题现在举例说明
现在有两个示例表如下:
Table1:表中记录和字段如下
Name_key     Phone     E_mail                                   
---------------------------------------------------------------------
David        110    david@sdic.com.cn                       
Davy        120    avy@sdic.com.cn                        
John        130    john@sdic.com.cn


Table2:
Name_key     age      Name_friend friend_phone 
-------- ----------- ----------- ------------ 
David    24    Snow        0100       
Davy     24    Snow        NULL    
kitty    10              cat             0130      


下面以Name_key 为连接字段进行连接
1. Inner join,
Select * from Table1 inner join Table2 on Table1.name_key=Table2.name_key

结果如下:


Name_key Phone       E_mail                                   Name_key age         Name_friend friend_phone 
-------- ----------- ---------------------------------------- -------- ----------- ----------- ------------ ------------
David    110         david@sdic.com.cn                        David    24          Snow        0100       


Davy     120         davy@sdic.com.cn                         Davy     24          Snow        NULL
    
    正如我们所期望的,返回了所有ON条件之后的匹配记录。


2. Left outer join
Select * from Table1 left outer join Table2 on Table1.name_key=Table2.name_key 

结果为:


Name_key Phone       E_mail                                   Name_key age         Name_friend friend_phone 
-------- ----------- ---------------------------------------- -------- ----------- ----------- ------------ 
David    110         david@sdic.com.cn                        David    24          Snow        0100       


Davy     120         davy@sdic.com.cn                         Davy     24          Snow        NULL


John     130         john@sdic.com.cn                         NULL     NULL        NULL        NULL


返回了左侧表的所有记录,因为John记录在右侧表无匹配记录,所以全为NULL


3. Right outer join
Select * from Table1 right outer join Table2 on Table1.name_key=Table2.name_key 

结果为:


Name_key Phone       E_mail                                   Name_key age         Name_friend friend_phone 
-------- ----------- ---------------------------------------- -------- ----------- ----------- ------------ 
David    110         david@sdic.com.cn                        David    24          Snow        0100  
     
Davy     120         davy@sdic.com.cn                         Davy     24          Snow        NULL


NULL     NULL        NULL                                        kitty    10          cat         0130       


返回了右侧表的所有记录,因为kitty记录在左侧表无匹配记录,所以全为NULL
    
4. Full outer join
Select * from Table1 full outer join Table2 on Table1.name_key=Table2.name_key

 结果为:


Name_key Phone       E_mail                                   Name_key age         Name_friend friend_phone 
-------- ----------- ---------------------------------------- -------- ----------- ----------- ------------ 
David    110         david@sdic.com.cn                        David    24          Snow        0100       


Davy     120         davy@sdic.com.cn                         Davy     24          Snow        NULL


John     130         john@sdic.com.cn                         NULL     NULL        NULL        NULL


NULL     NULL        NULL                                     kitty        10              cat            0130      


返回了2和3的并集。
    
5. Cross Join
Select * from Table1 cross join Table2 

结果为:


Name_key Phone       E_mail                                   Name_key age     Name_friend   friend_phone 
-------- ----------- ---------------------------------------- -------- ----------- ----------- ------------ 
David    110         david@sdic.com.cn                        David    24          Snow        0100   
    
Davy     120         davy@sdic.com.cn                         David    24          Snow        0100   
    
John     130         john@sdic.com.cn                           David    24          Snow        0100   
    
David    110         david@sdic.com.cn                        Davy     24          Snow        NULL


Davy     120         davy@sdic.com.cn                         Davy     24          Snow        NULL


John     130         john@sdic.com.cn                           Davy     24          Snow        NULL


David    110         david@sdic.com.cn                        kitty      10          cat             0130   
    
Davy     120         davy@sdic.com.cn                         kitty      10          cat             0130  
     
John     130         john@sdic.com.cn                           kitty      10          cat             0130       


返回了3*3=9条记录,同时Cross Join不能使用ON连接条件!否则出错。

使用了连接条件后,你为了得到相应的记录还要使用Where条件,你可以在连接语句后使用,如:
Select table1.name_key,table2.age,table1.email,table2.name_friend from table1 inner join on table2
Where table1.name_key=’David’


多表之间的操作
三个或更多表的连接,请继续使用连接命令即可,代码如下,不再举例。


Select *
Fom Table1 Inner join Table2 ON Table1.字段=Table2.字段
Inner join Table3 ON Table2.字段=Table3.字段
Where <选择条件>

0 0