SQL多表连接
大家在编程中经常遇到要在多个表中查询数据,在数据库的规范化中也经常把一个表经过投影分解成多个符合更高级范式的表。符合标准化的同时,自然要付出灵活性和性能的代价。把多个表连接在一起是一个耗时的操作,建议对那些经常用到的信息集中存放在一个表中,即使某些方面不符合规范化标准也可。多表连接操作最常用的是表和表之间取笛卡儿积,其他的还有Inner Join,left outer join,right outer join,full outer join,下面分别说明它们的区别。
使用语法:select 字段/* 表1 表连接操作类型 表2 on 条件
1 Inner Join
Inner Join 把两个表连接在一起,返回两个表中相匹配的记录,是2和3的交集。
2 Left outer join
Left outer join,左侧表所有的记录都返回,右侧匹配的记录返回,没有匹配的返回Null
3 Right outer join
与Left outer join相反,右侧的记录返回,左侧返回匹配的记录,没有匹配返回Null
4 Full outer join
2和3的并集。
5 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
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
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 * From Table1 Inner join Table2 ON Table1.字段=Table2.字段 Inner join Table3 ON Table2.字段=Table3.字段 Where <选择条件>