数据库中的数据不可能都放在同一张表中,这样效率是很低下的,所以都是分表存储。
但是我们往往需要获取的数据并不会都集中在一张表中,而是多张表都会涉及到,那怎么从多张表中获取到我们的数据?
这个时候就会用到多表连接 ----------》 在多个表之间通过一定的连接条件,使表之间 发生关联,进而能从多个表之间获取数据。
连接就是从笛卡尔积选取属性间满足一定条件的元组。
而连接又分为很多种连接:
①按照连接两张表的属性的运算符是否是“=”分为等值连接和非等值连接
如下两张表R和S
表R:
A | B | C |
a1 | b1 | 5 |
a1 | b2 | 6 |
b18 | b3 | 8 |
b1 | b4 | 12 |
表S:
S | E |
b1 | 3 |
b2 | 7 |
b3 | 10 |
b3 | 2 |
b5 | 2 |
等值连接:where R.B = S.B 含义:从RS两张表的笛卡尔结果集中选取R.B=S.B的结果集 结果如下:
A | R.B | C | S.B | E |
a1 | b1 | 5 | b1 | 3 |
a1 | b2 | 6 | b2 | 7 |
a2 | b3 | 8 | b3 | 10 |
a2 | b3 | 8 | b3 | 2 |
假如不想两个B列(R.B和S.B)同时出现,可以用等值连接中的特殊连接--》自然连接,连接结果会自动去除重复列
A | B | C | E |
a1 | b1 | 5 | 3 |
a1 | b2 | 6 | 7 |
a2 | b3 | 8 | 10 |
a2 | b3 | 8 | 2 |
非等值连接:where C < E(不一定要<号,可以使用between... and....语句之类) 含义:在笛卡尔积结果集中选取R表中C列数值大于E列数值的结果集 结果如下:
A | R.B | C | S.B | E |
a1 | b1 | 5 | b2 | 7 |
a1 | b1 | 5 | b3 | 10 |
a1 | b2 | 6 | b2 | 7 |
a1 | b2 | 6 | b3 | 10 |
a2 | b3 | 8 | b3 | 10 |
②根据连接结果是否返回某些列为空值的元组分为左外连接和右外连接
在连接查询中如果某些元组存在属性值为空时,在操作时这些元组就会被舍弃。
如下:假如R、S表都有列值为空的元组,当等值连接查询时,会查到一下结果,但是因为存在空值而被舍弃了,最后输出上述等值连接结果
A | B | C | E |
a1 | b1 | 5 | 3 |
a1 | b2 | 6 | 7 |
a2 | b3 | 8 | 10 |
a2 | b3 | 8 | 2 |
a2 | b4 | 12 | NULL |
NULL | b5 | NULL | 2 |
那想要在连接时输出这些存在空值的元组有什么办法?
①左外连接:就是只保留左边关系的悬浮元组(dangling tuple),而右边的元组属性为空值NULL
在Oracle中使用外部连接符号 (+)表示那一边取空值NULL:
取左外连接就是where语句为where R.B = S.B(+) , 结果如下:
A | B | C | E |
a1 | b1 | 5 | 3 |
a1 | b2 | 6 | 7 |
a2 | b3 | 8 | 10 |
a2 | b3 | 8 | 2 |
a2 | b4 | 12 | NULL |
①右外连接:就是只保留右边关系的悬浮元组(dangling tuple),而左边的元组属性为空值NULL
取左外连接就是where语句为where R.B(+) = S.B, 结果如下:
A | B | C | E |
a1 | b1 | 5 | 3 |
a1 | b2 | 6 | 7 |
a2 | b3 | 8 | 10 |
a2 | b3 | 8 | 2 |
NULL | b5 | NULL | 2 |
以上的(非)等值连接或者外部连接只讲到两张表的连接,假如需要超过两张表的连接的话,就使用AND连接两个连接语句
如:where table1.name = table2.name AND table2.name = table3.name ;
还有有时需要自生连接的情况下可以使用别名实现。
如:select one.A , two.B from R one ,R two where one.a = two.a;