您现在的位置是:主页 > news > 腾讯云网站备案流程/百度快照投诉中心
腾讯云网站备案流程/百度快照投诉中心
admin2025/5/12 16:53:12【news】
简介腾讯云网站备案流程,百度快照投诉中心,免费网站开发公司,国家信用信息公示网自然连接 自然连接(natural join)作用于两个关系,并产生一个关系作为结果。与两个关系的笛卡尔积不同,自然连接只考虑在两个关系的模式中都出现的那些属性上取值相同的元组对,而笛卡尔积将第一个关系的每个元组与第二…
自然连接
自然连接(natural join)作用于两个关系,并产生一个关系作为结果。与两个关系的笛卡尔积不同,自然连接只考虑在两个关系的模式中都出现的那些属性上取值相同的元组对,而笛卡尔积将第一个关系的每个元组与第二个关系的每个元组进行串接。
我们没有重复列出在两个关系的模式中都出现的属性,这样的属性只出现一次。还要注意属性的列出顺序:首先是两个关系模式中的公共属性,其次是只出现在第一个关系模式中的那些属性,最后是只出现在第二个关系模式中的那些属性。
自然连接运算的结果是关系。然后在这个关系上执行where和select子句。
在一条SQL查询的from子句中,可以用自然连接将多个关系结合在一起,如下所示:
select A1,A2,…,An
from r1 natural join r2 natural join…natural join rm
where P;
更为一般地,from子句可以写成如下形式:
from E1,E2…En
其中每个Ei可以是单个关系或一个涉及自然连接的表达式
为了发扬自然连接的优点,同时避免不正确的相等属性所带来的危险,SQL提供了一种自然连接的构造形式,它允许你来指定究竟需要哪些列相等。
join…using运算需要指定一个属性名列表。被连接的两个关系都必须具有指定名称的属性。请考虑运算r1 join r2 using(A1,A2),此运算与r1 natural join r2类似,只不过当t1.A1=t2.A1和t1.A2=t2.A2成立时,来自r1的元组t1和来自r2的元组t2就能匹配成对,即使r1和r2都具有名为A3的属性,也不需要t1.A3=t2.A3成立。
连接条件
SQL还支持另外一种形式的连接,其中可以指定任意的连接条件。
on条件允许在参与连接的关系上设置通用的谓词。该谓词的写法与where子句谓词类似,只不过使用的是关键词on而不是where。与using条件一样,on条件出现在连接表达式的末尾。
考虑下面的查询,它具有包含on条件的连接表达式:
select *
from student join takes on student.ID=takes.ID;
上述on条件表明:如果一个来自student的元组与一个来自takes的元组在ID上的取值相同,那么它们是匹配的。本例中的连接表达式与连接表达式student natural join takes几乎相同,因为自然连接运算也需要student元组和takes元组是匹配的。这两者之间的一个区别在于:在上述连接结果中,ID属性出现了两次,一次是student中的,另一次是takes中的,即便它们的ID属性值必须是相同的。
实际上,上述查询与以下查询是等价的:
select *
from student,takes
where student.ID=takes.ID;
正如我们如前所见,关系名被用来区分属性名ID,这样ID的两次出现分别表示为student.ID和takes.ID。只显示一次ID值的查询版本如下:
select student.ID as ID,name,dept_name,tot_cred,course_id,sec_id,semester,year,grade
from student join takes on student.ID=takes.ID;
/*这里因为通过select指定了结果关系的属性列表,所以不会出现两个ID*/
此查询结果与student和takes自然连接的结果完全相同
on条件可以表达任何SQL谓词,因而使用on条件的连接表达式就可以表示比自然连接更为丰富的连接条件。然而,正如我们前面的示例所示,使用带on条件的连接表达式的查询可以用不带on条件的等价表达式来替换,只要把on子句中的谓词移到where子句中即可。因此,on条件看起来似乎是一个冗余的SQL特征。
但是,引入on条件有两个很好的理由。
- 首先,我们马上就会看到,对于被称作外连接的这一类连接来说,on条件的表现与where条件的确是不同的
- 其次,如果在on子句中指定连接条件,并在where子句中出现其余的条件,这样的SQL查询通常更容易让人读懂
外连接
参与连接的任何一个或两个关系中的某些元组可能会因为“未匹配”而丢失。外连接运算(outer join)运算与我们已经学过的连接运算类似,它通过在结果中创建包含空值的元组,来保留那些在连接中会丢失的元组。
共有三种形式的外连接:
- 左外连接(left outer join)只保留出现在左外连接运算之前(左边)的关系中的元组。
- 右外连接(right outer join)只保留出现在右外连接运算之后(右边)的关系中的元组。
- 全外连接(full outer join)保留出现在两个关系中的元组。
相比而言,为了与外连接运算相区分,我们此前学习的不保留未匹配元组的连接运算被称为内连接(inner join)运算。
我们可以按照如下方式计算左外连接:
首先,像前面那样计算出内连接的结果;然后,对于内连接的左侧关系中任意一个与右侧关系中任何元组都不匹配的元组t,向连接结果中加入一个元组r,r的构造如下:
- 元组r从左侧关系得到的属性被赋为来自元组t的值
- r的其余属性被赋为空值
右外连接与左外连接是对称的,来自右侧关系的、不匹配左侧关系中任何元组的元组被补上空值,并加入到右外连接的结果中。
全外连接是左外连接和右外连接类型的联合。在内连接结果被计算出来之后,该运算将来自左侧关系、不匹配右侧关系中任何元组的那些元组添上空值并把它们加到结果中。类似地,它将来自右侧关系的、不匹配左侧关系中任何元组的那些元组也添上空值并把它们加到结果中。换言之,全外连接是左外连接和相应的右外连接的并运算(在那些只实现左外连接和右外连接的系统,特别是MySQL中,这正是人们编写完整外连接的方式)。
on和where对外连接的表现是不同的。其原因是:
外连接只为那些相应的“内”连接结果没有贡献的元组增加补上空值的元组。on条件是外连接声明的一部分,但where字句不是。
在我们的示例中,ID为70557的学生“Snow”所对应的student元组的情况就说明了这样的差异。假设我们按这样的方式来修改前述查询:把on子句谓词换到where子句中,并使用一个为true的on条件。
select *
from student left outer join takes on true
where student.ID=takes.ID;
早先的查询使用带on条件的左外连接,包括元组(70557,Snow,Physics,0,null,null,null,null,
,null,null),因为在takes中没有ID=70557的元组。然后在后面的查询中,每个元组都满足连接条件true,因此外连接不会产生补上空值的元组。外连接实际上产生了两个关系的笛卡尔积。因为在takes中没有ID=70557的元组,每次当外连接中出现name=“Snow”的元组时,student.ID与takes.ID的取值必然是不同的,并且这样的元组会被where子句谓词排除掉。从而,学生Snow不会出现在后面查询的结果中。
连接类型和条件
为了把常规连接和外连接区分开来,在SQL中把常规连接称作内连接。这样连接子句就可以指定用内连接而不是外连接来说明使用的是常规连接。然而关键词inner是可选的,当join子句中没有使用outer前缀时,缺省的连接类型是内连接。
类似地,自然连接(natural join)等价于自然内连接(natural inner join)。
连接类型 |
---|
inner join |
left outer join |
right outer join |
full outer join |
连接条件 |
---|
natural |
on < predicate > |
using (A1,A2,…,An) |
任意的连接方式(内连接、左外连接、右外连接或全外连接)可以和任意的连接条件(自然连接、using条件连接或on条件连接)进行组合。