本节目录
1、连接表达式
在之前简单介绍了自然连接运算,SQL提供了连接运算的其他形式,包括能够指定显式的连接谓词,能够在结果中包含被自然连接排除在外的元组。
1.1 连接条件
前面介绍的join...using子句,是一种自然连接的形式,只需要在指定属性上的取值匹配,SQL支持另一种形式的连接,其中可以指定任意的连接条件。
on条件允许在参与连接的关系上设置通用的谓词,该谓词的写法与where子句谓词类似,只不过使用关键字on而不是where,与using条件一样,on条件出现在连接表达式的末尾。如下查询:
上述on条件表明,如果一个来自student的元组和一个来自takes的元组在ID上的取值相同,那么它们是匹配的。上例中连接表达式与自然连接几乎是一样的。关系名用来区分属性名ID。
on条件可以表示任何SQL谓词,因此使用on条件的连接表达式就可以表示比自然连接更为丰富的连接条件。使用带有on条件的连接表达式查询可以用不带on的等价表达式来替换,但是on并不是多余的,相反,on有两个优点,首先对于外连接的这类连接来说,on条件的表现与where条件不同,其次,如果在on子句中指定连接条件,并在where子句中出现其余条件,这样的查询更容易让人读懂。
1.2 外连接
如果要一个显示出所有学生的列表,并且显示出它们的在不同关系中的属性。如下:
遗憾的是,上述查询会出现一定的问题,如果有一些学生,他没有选任何课程,那么在takes关系中没有他的ID,这样查询结果会抛弃掉这个学生,也就是说他不会出现在自然连接的结果中。外连接运算与我们学过的连接运算类似,但是在结果中创建包含空值的元组的方式,保留了那些在连接中丢失的元组。
例如,为了保证前面的学生出现在结果中,可以连接结果中加入一个元组,它来自student关系的属性的值设置为该学生的值,剩下takes的属性的值设置为null。
实际上有三种形式的外连接。
*左外连接:只保留出现在左外连接运算之前的关系中的元组。
*右外连接:只保留出现在右外连接运算之后的关系中的元组。
*全外连接:保留出现在两个关系中的元组。
为了与外连接运算区分,此前学习的不保留未匹配元组的连接运算称作内连接运算。左连接运算:首先像前面那样计算出内连接的结果,然后对内连接的左侧关系中任意一个与右侧关系中任何元组都不匹配符的元组t,向连接结果中加入一个元组r,r的构造如下:
*元组r从左侧关系得到的属性被赋给t中的值。
*r的其他属性被赋值为空值。
其查询语句如下:
右外连接和左外连接是对称的,来自右侧关系中的不匹配左侧关系任何元组的元组被补上空值,并加入到右外连接的结果中。这样如果用右外连接重写前面的查询,只需要交换关系的次序。如下:
全外连接是左外连接和右外连接的组合,在内连接结果计算出来后,左侧关系中不匹配右侧关系的人和元组都被添上空值并加到结果中。类似的,右侧关系中不匹配左侧关系任何的元组也被添加上空值被加到结果中。on子句可以和外连接一起使用。前面提到,on和where在外链接中表现不同,原因就是外连接只为那些对应内连接结果没有贡献的元组补上空值并加入结果,on条件是外连接声明的一部分,但where子句不是。
1.3 连接类型和条件
为了把常规连接和外连接区分开,SQL中把常规连接称为内连接,这样的连接子句可以用inner join来替换outer join,说明适用的是常规连接,关键字inner 是可选的,join子句中没有使用outer 前缀也就是其连接类型是inner join。
2、视图
在前面所有的例子中,我们一直在逻辑模型层操作,也就是我们假定了给定的集合中的关系都是实际存储在数据库中的。让所有用户看到整个逻辑模型是不合适的,出于安全考虑,可能要向用户隐藏特定的数据。
SQL允许通过查询来定义虚关系,它在概念上包含查询的结果,婿关系并不预先计算并存储,而是在是用虚关系的时候才通过执行查询被计算出来。
任何像这种不是逻辑模型的一部分,但作为虚关系对用户可见的关系称为视图。
2.1 视图定义
在SQL中用create view 定义视图,为了定义视图,必须给视图一个名称,并且必须提供计算视图的查询,create view 命令的格式为:
其中<query expression>可以是任何合法的查询表达式,v表示视图名。例如,在一个关系中,不想将所有属性都授权,那么可以建立一个视图,如下:
前面说过,视图关系在概念上包含查询结果重的元组,但是不进行预计算和存储,相反数据库系统存储与视图关系相关联的查询表达式,当视图关系被访问时,其中元组是通过计算查询结果而创建出来的,从而视图关系是在需要的才被创建的。
2.2 SQL查询中使用视图
一旦定义了一个视图,就可以使用视图名指代该视图生成的虚关系。在查询中,试图可以出现在任何关系名可以出现的地方。视图的属性名可以按照下面的方式显式指定:
上面视图给出了每个系中所有教师的工资总和,因为表达式sum(salary)没有名称,其属性名是在视图定义中显式指定的。直觉上,在任何给定时刻,视图关系中的元组集是该时刻视图定义中查询表达式的计算结果,因此一个视图关系被