left join、inner join 区别--上

来源:互联网 发布:上海关键词seo公司 编辑:程序博客网 时间:2024/05/21 11:02

 示例用表
雇员表(Employee) 
LastName DepartmentID 
Rafferty 31 
Jones 33 
Steinberg 33 
Robinson 34 
Smith 34 
Jasper NULL 
部门表(Department) 
DepartmentID DepartmentName 
31 Sales 
33 Engineering 
34 Clerical 
35 Marketing 
注: "Marketing" 部门目前没有员工列出. 同样, 雇员 "Jasper" 不在 Department 表中的任何一个部门。

内连接
内连接(inner join)是应用程序中用的普遍的"连接"操作, 它一般都是默认的连接类型. 内连接基于连接谓词将两张表(如 A 和 B)的列组合在一起, 产生新的结果表. 查询会将 A 表的每一行和 B 表的每一行进行比较, 并找出满足连接谓词的组合. 当连接谓词被满足, A 和 B 中匹配的行会按列组合(并排组合)成结果集中的一行. 连接产生的结果集, 可以定义为首先对两张表做笛卡尔积(交叉连接) -- 将 A 中的每一行和 B 中的每一行组合, 然后返回满足连接谓词的记录. 实际上 SQL 产品会尽可能用其他方式去实现连接, 笛卡尔积运算是非常没效率的.

SQL 定义了两种不同语法方式去表示"连接". 首先是"显示连接符号", 它显示地使用关键字 JOIN, 其次是"隐式连接符号", 它使用所谓的"隐式连接符号". 隐式连接符号把需要连接的表放到 SELECT 语句的 FROM 部分, 并用逗号隔开. 这样就构成了一个"交叉连接", WHERE 语句可能放置一些过滤谓词(过滤条件). 那些过滤谓词在功能上等价于显式连接符号.

内连接"可以进一步被分为: 相等连接, 自然连接, 和交叉连接(见下).

程序要应该特别注意连接依据的列可能包含 NULL 值, NULL 值不与任何值匹配(甚至和它本身) -- 除非连接条件中显式地使用 IS NULL 或 IS NOT NULL 等谓词.

例如, 下面的查询通过 Employee 表和 Department 表共有的属性 DepartmentID 连接两表. 在两表 DepartmentID 匹配之处(如连接谓词被满足), 查询将组合两表的 LastName, DepartmentID 和DepartmentName 等列, 把它们放到结果表的一行(一条记录)里. 当 DepartmentID 不匹配, 就不会往结果表中生成任何数据.

显式的内连接实例:

SELECT *
FROM employee 
  INNER JOIN department 
  ON employee.DepartmentID = department.DepartmentID
等价于:

SELECT *  
FROM employee, department 
WHERE employee.DepartmentID = department.DepartmentID

显式的内连接的输出结果:

Employee.LastName Employee.DepartmentID Department.DepartmentName Department.DepartmentID 
Robinson 34 Clerical 34 
Jones 33 Engineering 33 
Smith 34 Clerical 34 
Steinberg 33 Engineering 33 
Rafferty 31 Sales 31 

注 雇员 "Jasper" 和部门 "Marketing" 都未出现. 它们在预期得到的表中没有任何匹配的记录: "Jasper" 没有关联的部门, 而号码为35的部门中没有任何雇员. 这样, 在"连接"后的表中, 就没有关于 Jasper 或 Marketing 的信息了. 相对于预期的结果, 这个行为可能是一个微妙的臭虫(bug). 外连接可能可以避免这种情况.

外连接
外连接并不要求连接的两表的每一条记录在对方表中都一条匹配的记录. 连接表保留所有记录 -- 甚至这条记录没有匹配的记录也要保留. 外连接可依据连接表保留左表, 右表或全部表的行而进一步分为左外连接, 右外连接和全连接.

(在这种情况下left<左> 和 right<右> 表示 JOIN 关键字的两边.)

在标准的 SQL 语言中, 外连接没有隐式的连接符号.

[编辑] 左外连接
左外连接(left outer join), 亦简称为左连接(left join), 若 A 和 B 两表进行左外连接, 那么结果表中将包含"左表"(即表 A)的所有记录, 即使那些记录在"右表" B 没有符合连接条件的匹配. 这意味着即使 ON 语句在 B 中的匹配项是0条, 连接操作还是会返回一条记录, 只不过这条记录的中来自于 B 的每一列的值都为 NULL. 这意味着左外连接会返回左表的所有记录和右表中匹配记录的组合(如果右表中无匹配记录, 来自于右表的所有列的值设为 NULL). 如果左表的一行在右表中存在多个匹配行, 那么左表的行会复制和右表匹配行一样的数量, 并进行组合生成连接结果.

如, 这允许我们去找到雇员的部门时, 显示所有雇员, 即使这个雇员还没有关联的部门. (在上面的内连接部分由一个相反的例子, 没有关联的部门号的雇员在结果中是不显示的).

左外连接实例: (相对于内连接增添的行用斜体标出)

SELECT *  
FROM employee LEFT OUTER JOIN department  
  ON employee.DepartmentID = department.DepartmentID
Employee.LastName Employee.DepartmentID Department.DepartmentName Department.DepartmentID 
Jones 33 Engineering 33 
Rafferty 31 Sales 31 
Robinson 34 Clerical 34 
Smith 34 Clerical 34 
Jasper NULL NULL NULL 
Steinberg 33 Engineering 33