请教,两种连接方式的区别
select a.id,a.[root_id],b.[name],a.[name] from detail a,[root] b
where a.root_id=b.id
select a.id,a.[root_id],b.[name],a.[name] from detail a
left join [root] b on a.root_id=b.id
[解决办法]
--查询分析器中执行:
--建表table1,table2:
create table table1(id int,name varchar(10))
create table table2(id int,score int)
insert into table1 select 1, 'lee '
insert into table1 select 2, 'zhang '
insert into table1 select 4, 'wang '
insert into table2 select 1,90
insert into table2 select 2,100
insert into table2 select 3,70
如表
-------------------------------------------------
table1|table2|
-------------------------------------------------
idname|idscore|
1lee|190|
2zhang|2100|
4wang|370|
-------------------------------------------------
以下均在查询分析器中执行
一、外连接
1.概念:包括左向外联接、右向外联接或完整外部联接
2.左连接:left join 或 left outer join
(1)左向外联接的结果集包括 LEFT OUTER 子句中指定的左表的所有行,而不仅仅是联接列所匹配的行。如果左表的某行在右表中没有匹配行,则在相关联的结果集行中右表的所有选择列表列均为空值(null)。
(2)sql语句
select * from table1 left join table2 on table1.id=table2.id
-------------结果-------------
idnameidscore
------------------------------
1lee190
2zhang2100
4wangNULLNULL
------------------------------
注释:包含table1的所有子句,根据指定条件返回table2相应的字段,不符合的以null显示
3.右连接:right join 或 right outer join
(1)右向外联接是左向外联接的反向联接。将返回右表的所有行。如果右表的某行在左表中没有匹配行,则将为左表返回空值。
(2)sql语句
select * from table1 right join table2 on table1.id=table2.id
-------------结果-------------
idnameidscore
------------------------------
1lee190
2zhang2100
NULLNULL370
------------------------------
注释:包含table2的所有子句,根据指定条件返回table1相应的字段,不符合的以null显示
4.完整外部联接:full join 或 full outer join
(1)完整外部联接返回左表和右表中的所有行。当某行在另一个表中没有匹配行时,则另一个表的选择列表列包含空值。如果表之间有匹配行,则整个结果集行包含基表的数据值。
(2)sql语句
select * from table1 full join table2 on table1.id=table2.id
-------------结果-------------
idnameidscore
------------------------------
1lee190
2zhang2100
4wangNULLNULL
NULLNULL370
------------------------------
注释:返回左右连接的和(见上左、右连接)
二、内连接
1.概念:内联接是用比较运算符比较要联接列的值的联接
2.内连接:join 或 inner join
3.sql语句
select * from table1 join table2 on table1.id=table2.id
-------------结果-------------
idnameidscore
------------------------------
1lee190
2zhang2100
------------------------------
注释:只返回符合条件的table1和table2的列
4.等价(与下列执行效果相同)
A:select a.*,b.* from table1 a,table2 b where a.id=b.id
B:select * from table1 cross join table2 where table1.id=table2.id (注:cross join后加条件只能用where,不能用on)
三、交叉连接(完全)
1.概念:没有 WHERE 子句的交叉联接将产生联接所涉及的表的笛卡尔积。第一个表的行数乘以第二个表的行数等于笛卡尔积结果集的大小。(table1和table2交叉连接产生3*3=9条记录)
2.交叉连接:cross join (不带条件where...)
3.sql语句
select * from table1 cross join table2
-------------结果-------------
idnameidscore
------------------------------
1lee190
2zhang190
4wang190
1lee2100
2zhang2100
4wang2100
1lee370
2zhang370
4wang370
------------------------------
注释:返回3*3=9条记录,即笛卡尔积
4.等价(与下列执行效果相同)
A:select * from table1,table2
[解决办法]
--内联
select a.id,a.[root_id],b.[name],a.[name]
from detail a,[root] b
where a.root_id=b.id
--左外联
select a.id,a.[root_id],b.[name],a.[name] from detail a
left join [root] b on a.root_id=b.id
[解决办法]
select a.id,a.[root_id],b.[name],a.[name] from detail a
left join [root] b on a.root_id=b.id
这叫做左连接,只要a表中记录,而在b表中没有一个id与a表中的id相同,也会被提取出来。b
表相应的字段的值会被默认为null。
例如:
a表中的纪录为:
id name
1 '1 '
2 '2 '
b表中的记录为:
id2 name2
1 '1 '
1 '11 '
则取到的结果是:
id name id2 name2
1 '1 ' 1 '1 '
1 '1 ' 1 '11 '
2 '2 ' null null
而如果我们用:
select a.id,a.[root_id],b.[name],a.[name] from detail a,[root] b
where a.root_id=b.id
他要求两边都有的情况才提取出来,也就是结果为:
id name id2 name2
1 '1 ' 1 '1 '
1 '1 ' 1 '11 '
[解决办法]
一楼讲的很清楚了。
第一种相当于inner join,两表都有的数据,才会显示出来。
第二种会显示两边相等的数据,也会显示左边表自己独有的数据。
[解决办法]
一般内联效率高, 内联可选择的优化方案更多.
特别是在多表关联的时候, 查询优化器能够有效地确定先做那些表的联接, 然后再做那些表的联接. 而外联由于查询结果要求的限制, 不容易调整联接的表的顺序.