使用外连接引发的一点思考
外连接查询想必是不用多讲了
Left outer join:以等号左边的表为标准,对等号右边的表按条件进行过滤
Right outer join:原理同上
Full outer join:这个我相信大家和我一样都很少用到了,以上两种连接查询结果的并集
举个例子来说说
有两个表:#tb1(id,scourse ,sclass ,sbook)、#tb2(id,sclass ,steacher,sbook),我的目的是想得到一个这样的结果(sclass,scourse,sbook,steacher)。很自然的我就想到利用外连接,代码如下:(没有问题)
代码
create table #tb1(
id int identity(1,1) primary key,
scourse varchar(30),
sclass varchar(30),
sbook varchar(30)
)
insert into #tb1
select 'cs001','cl001','bo001'
union
select 'cs002','cl002','bo002'
union
select 'cs003','cl003','bo003'
create table #tb2(
id int identity(1,1) primary key,
sclass varchar(30),
steacher varchar(30),
sbook varchar(30)
)
insert into #tb2
select 'cl001','te001','bo001'
union
select 'cl002','te002','bo002'
union
select 'cl004','te004','bo004'
union
select 'cl001','te003','bo002'
select * from #tb1
select * from #tb2
select a.id,a.scourse,a.sclass,a.sbook,steacher from #tb1 a Left join #tb2 b ON
a.sclass=b.sclass and a.sbook= b.sbook
create table #tb1(
id int identity(1,1) primary key,
scourse varchar(30),
sclass varchar(30),
sbook varchar(30)
)
insert into #tb1
select 'cs001','cl001','bo001'
union
select 'cs002','cl002','bo002'
union
select 'cs003','cl003','bo003'
create table #tb2(
id int identity(1,1) primary key,
sclass varchar(30),
steacher varchar(30),
sbook varchar(30)
)
insert into #tb2
select 'cl001','te001','bo001'
union
select 'cl002','te002','bo002'
union
select 'cl004','te004','bo004'
union
select 'cl001','te003','bo002'
select * from #tb1
select * from #tb2
select a.id,a.scourse,a.sclass,a.sbook,steacher from #tb1 a Left join #tb2 b ON
a.sclass=b.sclass and a.sbook= b.sbook
现在的结果:
sclass scourse sbook steacher
cl001 cs001 bo001 te001
cl002 cs002 bo002 te002
cl003 cs003 bo003 NULL
到这里,一切都很好。我期望的结果相当于在表#tb1中增加一列steacher,并且最终结果的记录条数与#tb1的记录条数要一致
我对上面的代码稍加修改,改变一下#tb2的记录
代码
create table #tb1(
id int identity(1,1) primary key,
scourse varchar(30),
sclass varchar(30),
sbook varchar(30)
)
insert into #tb1
select 'cs001','cl001','bo001'
union
select 'cs002','cl002','bo002'
union
select 'cs003','cl003','bo003'
create table #tb2(
id int identity(1,1) primary key,
sclass varchar(30),
steacher varchar(30),
sbook varchar(30)
)
insert into #tb2
select 'cl001','te001','bo001'
union
select 'cl002','te002','bo002'
union
select 'cl004','te004','bo004'
union
select 'cl001','te003','bo002'
union
select 'cl001','te003','bo001'
union
select 'cl001','te004','bo001'
select * from #tb1
select * from #tb2
select a.id,a.scourse,a.sclass,a.sbook,steacher from #tb1 a Left join #tb2 b ON
a.sclass=b.sclass and a.sbook= b.sbook
create table #tb1(
id int identity(1,1) primary key,
scourse varchar(30),
sclass varchar(30),
sbook varchar(30)
)
insert into #tb1
select 'cs001','cl001','bo001'
union
select 'cs002','cl002','bo002'
union
select 'cs003','cl003','bo003'
create table #tb2(
id int identity(1,1) primary key,
sclass varchar(30),
steacher varchar(30),
sbook varchar(30)
)
insert into #tb2
select 'cl001','te001','bo001'
union
select 'cl002','te002','bo002'
union
select 'cl004','te004','bo004'
union
select 'cl001','te003','bo002'
union
select 'cl001','te003','bo001'
union
select 'cl001','te004','bo001'
select * from #tb1
select * from #tb2
select a.id,a.scourse,a.sclass,a.sbook,steacher from #tb1 a Left join #tb2 b ON
a.sclass=b.sclass and a.sbook= b.sbook
我就简单的给#tb2增加了几条记录
现在的结果:
sclass scourse sbook steacher
cl001 cs001 bo001 te001
cl001 cs001 bo001 te003
cl001 cs001 bo001 te004
cl002 cs002 bo002 te002
cl003 cs003 bo003 NULL
现在可以看出来为什么外连接查询时结果比预想的多了吧
由于#tb2按要求:#tb1.sclass=#tb2.sclass and #tb1.sbook= #tb2.sbook过滤后得到的结果不是唯一的
所以在处理这样的情况时需要先处理#tb2,使其按条件#tb1.sclass=#tb2.sclass and #tb1.sbook= #tb2.sbook过滤后结果唯一才能达到预期效果
ps:任何时候都要认真分析你所操作的对象,并且动手实践去了解你所使用的对象
用发现的眼光来看这个互联网,总有我们立脚的地方!——北纬28.33