之前一直对数据库里面的外连接有些疑惑,理解的不是很透彻,今天总算自己建了个表,详细地对照了几种写法,总算彻底搞清楚了。
基本概念
左连接、右连接就是数据库里面的关键字 left join 和 right join, 当然在oracle里面也可以在某个字段的后面加上(+)来表示外连接
左连接保留出现在left join左边的关系中的元组,也就是允许右边关系中为空;通俗一点:Left join 会从左表中返回所有的行,即便在右表中没有找到匹配的项。
同理右连接保留出现在right join右边的关系中的元组,也就是允许左边关系中为空;Right join会总右表中返回所有的行,即便在左表中没有找到匹配的项。
在Oracle中
select * from a left join b on a.xxx=b.xxx和
select * from a, b where a.xxx = b.xxx(+)是等价的。
举例说明
再难理解的知识点放到实际中去操作一下,立刻就能理解地透彻很多。
我们假设现在有两张表 a1 和a2
a1:
a2:
这两个表中有共同的字段id表示相同的含义,bcde字段可以看做不同的4列;
可以看到这两个表中有一个相同的id 1;那如果不做任何选择,a1和a2的笛卡尔积是什么样子呢?
试着执行下列语句:
select * from a1, a2你会得到如下的结果:
笛卡尔积是个全乘积,但是单单得到笛卡尔积是没有什么用的,因为这个集合很大,而且很多行并没有什么实际意义,这时候就需要加上where语句来选择出真正有用的列
试着执行下列语句:
select a.id, b, c, d, e from a,b where a.id=b.id;注意,如果笛卡尔积中的字段是唯一的,可以不用在select的时候标明,也就是说不用写 select a.c , b.d, b.e 等。
这时候得到的结果一定是只有1行的,也就是
这个很容易理解,也是我们最常使用的,那如果我们想得到a1表中的所有id,而无论他在不在a2中呢,改如何做呢?
试试下列语句中的任意一条:
select a.id,b,c,d,e from a,b where a.id=b.id(+); select a.id,b,c,d,e from a left join b on a.id = b.id;你会得到什么结果呢?
是的,你会发现我们把a1表中所有的id都选择了出来,如果这个id没有在a2表中出现,那么这一行就会留空。
看到这里,一个更通俗易懂的理解外连接的诀窍就是:+号出现的那一侧允许出现NULL
当然,我们可以通过在d和e字段加上nvl(d,0)语句来把相应的null值改成我们想要的数据。
目的:
到了这里,相信我们已经对外连接有个清晰的认识了,不过为什么我们需要外连接呢??
举个简单的例子,假如a1表是学生信息表,a2表示学生选课表
由于某种特殊原因,学号为201400002的那位女同学就是没有选一门课,不管她是休学1年还是已经修满学分了,就是任性,一门课也不修,那如果我们想统计学生的姓名,年龄,选课信息等等,如果不使用外连接,很容易地就把这位女同学漏掉了,而一个a.id=b.id(+)就足以规避这种特殊情况带来的错误了!