(下)
下篇将以LEFT OUTER JOIN 操作为例,对SQLServer2005中内外连接的逻辑查询处理步骤进行详解
具体查询实例来自上篇(SQLServer2005中的OUTER JOIN 和 INNER JOIN 精析(上)):
select a.u_id,a.u_name,b.u_other
from table_one a LEFT OUTER JOIN table_two b
ON a.u_id=b.u_id
步骤一:执行笛卡尔乘积(交叉连接)
对FROM 子句的前两个表执行笛卡尔乘积(交叉连接或未限定的链接),生成虚拟表VT1。VT1左表的行和右表的行的每一个可能的组合都包含一行。例如上篇实例中的左表包含3行,右表包含9行,VT1将包括3*9行。VT1中的列由该列的源表名限定(如果指定了别名则使用别名)。
根据实例查询语句:from table_one a...LEFT OUTER JOIN table_two b
你将得到如下表所示的虚拟表VT1(具体详细结果请参照上篇)
a.u_id a.u_name b.u_id b.u_other
1 'AA' 1 'thanks a lot'
1 'AA' 1 'thanks a lot'
. . . .
. . . .
1 'AA' 66 'excellent'
2 'BB' 1 'thanks a lot'
2 'BB' 1 'thanks a lot'
. . . .
. . . .
2 'BB' 66 'excellent'
3 'CC' 1 'thanks a lot'
3 'CC' 1 'thanks a lot'
. . . .
. . . .
3 'CC' 66 'excellent'
步骤二:应用ON筛选器(连接条件)
ON筛选器是可以用于查询的三个筛选器(ON,WHERE,HAVING)中的第一个。ON筛选器中的逻辑表达式被应用到上一步返回的虚拟表(VT1)中的所有行。只有是(连接条件)为TRUE的那些行才会包含在由步骤2返回的虚拟表(VT2)中
根据实例查询语句:ON a.u_id=b.u_id
步骤二返回的虚拟表VT2
Math? a.u_id a.u_name b.u_id b.u_other
TRUE 1 'AA' 1 'very good'
TRUE 1 'AA' 1 'thanks a lot'
TRUE 1 'AA' 1 'thanks a lot'
TRUE 2 'BB' 2 NULL
TRUE 3 'CC' 3 'very good'
TRUE 3 'CC' 3 'thanks a lot'
步骤三:添加外部行(Outer Row)
这一步只与外部链接(outer join)有关。通过指定一种外部链接(LEFT,RIGHT或FULL),可以把一个或两个输入表标记为保留表。把一个表标记为保留表表示你希望返回该表的所有行,即使<连接条件>过滤掉了一些行。左外连接(left outer join) 把左表标记为保留表,右外连接(right outer join)把右表表示为保留表,完全外连接(full outer join)把两个表都标记为保留表。步骤3返回VT2中的行以及保留表在步骤2被过滤掉的行。保留表中的这些行被称为外部行。外部行中非保留表的属性被赋值为NULL。最后生成虚拟表VT3
在上面的实例中,保留表是table_one
语句:table_one a LEFT OUTER JOIN table_two b
只有table_one 中u_id为2的记录没有找到匹配项,因此u_id为2的记录被添加到上一步骤返回的虚拟表,b.u_other 的属性为NULL,生成虚拟表VT3,即得到最终的结果!